?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Process Commands' ??
MODULE clm$process_commands;

{
{ PURPOSE:
{   This module contains the routines that interpret an individual command or control statement.
{   This entails parsing the command image, using the command list to search for the appropriate processor,
{   and passing control to that processor in the appropriate fashion (call, load and call, execute, or
{   PROCedure call.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ame$lfn_program_actions
*copyc clc$command_cleanup_completed
*copyc clc$compiling_for_test_harness
*copyc clc$exiting_condition
*copyc clc$standard_file_names
*copyc cle$ecc_command_processing
*copyc cle$ecc_control_statement
*copyc cle$ecc_lexical
*copyc cle$ecc_utilities
*copyc cle$unexpected_call_to
*copyc cle$work_area_overflow
*copyc clk$process_command
*copyc cll$comment_command
*copyc clt$async_command_parameters
*copyc clt$command_line
*copyc clt$command_line_index
*copyc clt$command_line_size
*copyc clt$command_list
*copyc clt$command_or_function_source
*copyc clt$command_resource_statistics
*copyc clt$i_parameter_list_contents
*copyc clt$interpreter_modes
*copyc clt$lexical_unit_kinds
*copyc clt$scl_procedure
*copyc clt$scl_procedure_header
*copyc cyd$run_time_error_condition
*copyc fsc$compiling_for_test_harness
*copyc ife$error_codes
*copyc llt$command_description
*copyc llt$program_description
*copyc loc$task_services_library_name
*copyc ost$caller_identifier
*copyc ost$status
*copyc pfe$error_condition_codes
?? POP ??
*copyc amv$nil_file_identifier
*copyc bap$process_pt_request
*copyc clp$access_command_file
*copyc clp$append_status_parse_state
*copyc clp$assignment_statement
*copyc clp$case_selection_statement
*copyc clp$change_variable
*copyc clp$check_name_for_control
*copyc clp$close_command_file
*copyc clp$close_command_library
*copyc clp$construct_path_handle_name
*copyc clp$convert_file_ref_to_string
*copyc clp$convert_str_to_path_handle
*copyc clp$convert_string_to_file
*copyc clp$echo_command
*copyc clp$echo_trace_information
*copyc clp$execute_named_task
*copyc clp$find_cmnd_or_func_in_prog
*copyc clp$find_command_list
*copyc clp$find_connected_files
*copyc clp$find_current_block
*copyc clp$find_utility_block
*copyc clp$find_working_catalog
*copyc clp$get_command_statistics
*copyc clp$get_fs_path_string
*copyc clp$get_log_secure_parameters
*copyc clp$get_work_area
*copyc clp$ignore_rest_of_file
*copyc clp$initialize_application_info
*copyc clp$initialize_parse_state
*copyc clp$load_from_library
*copyc clp$load_system_entry_point
*copyc clp$log_command_line
*copyc clp$parse_command
*copyc clp$pop_block_stack
*copyc clp$pop_input_stack
*copyc clp$pop_terminated_blocks
*copyc clp$process_command_file
*copyc clp$process_exit_condition
*copyc clp$process_proc_parameters
*copyc clp$push_command_block
*copyc clp$push_command_proc_block
*copyc clp$restore_work_area_positions
*copyc clp$save_work_area_positions
*copyc clp$search_command_library
*copyc clp$search_command_table
*copyc clp$set_prev_cmnd_name_and_stat
*copyc clp$trimmed_string_size
*copyc clp$validate_local_file_name
*copyc clv$ijl_ordinal
*copyc clv$intrinsic_commands
*copyc clv$local_catalog_handle_name
*copyc clv$operator_commands
*copyc clv$standard_files
*copyc clv$system_commands
*copyc fsv$evaluated_file_reference
  ?IF fsc$compiling_for_test_harness AND clc$compiling_for_test_harness THEN
*copyc fsv$test_harness_cmnds
  ?IFEND
*copyc jmp$get_job_attributes
*copyc jmp$logout
*copyc jmp$system_job
*copyc osp$append_status_parameter
*copyc osp$check_for_desired_mf_class
*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
*copyc osp$set_desktop_interaction
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc osp$system_error
*copyc osv$initial_exception_context
*copyc osv$lower_to_upper
*copyc pmf$job_mode
*copyc pmp$continue_to_cause
*copyc pmp$execute
*copyc pmp$execute_within_task
*copyc pmp$get_program_description
*copyc pmp$get_program_size
*copyc pmp$get_task_id
*copyc pmp$inward_call
*copyc pmp$load
*copyc pmp$log_ascii
*copyc sfp$emit_audit_statistic
*copyc sfp$emit_statistic

?? TITLE := 'Command Search State / Statistic Types', EJECT ??

  TYPE
    clt$command_search_state = record
      caller_ring: ost$valid_ring,
      cause_condition: ^clt$when_condition,
      command: ^clt$command_line,
      command_block: ^clt$block,
      command_from_execute_command: boolean,
      command_echoing_activated: boolean,
      command_echoing_completed: boolean,
      command_list: ^clt$command_list,
      command_logging_completed: boolean,
      command_log_option: clt$command_log_option,
      command_reference_text: ^clt$command_line,
      data: clt$processed_command_data,
      device_class: rmt$device_class,
      effective_search_mode: clt$command_search_modes,
      escaped_command: boolean,
      file: clt$file,
      file_id: amt$file_identifier,
      found: boolean,
      ignore_status: ost$status,
      interpreter_mode: clt$interpreter_modes,
      label: ost$name,
      library_search_info: clt$command_library_search_info,
      name: clt$name,
      nested_commands_can_be_echoed: boolean,
      parse: clt$parse_state,
      path: fst$path,
      path_description_obtained: boolean,
      path_size: fst$path_size,
      prev_cmnd_name_and_stat_set: boolean,
      prompting_requested: boolean,
      ring_attributes: amt$ring_attributes,
      search_level: clt$search_level,
      search_name: clt$name,
      separator: clt$lexical_unit_kind,
      source: clt$command_or_function_source,
      work_area: ^^clt$work_area,
    recend;

  TYPE
    clt$processed_command_data = record
      filler: 0 .. 255,
      from_job_command_file: boolean,
      generic_source: clt$generic_command_source,
      ordinal: clt$named_entry_ordinal,
      call_method: clt$command_call_method,
    recend;

  TYPE
    clt$generic_command_source = (clc$gcs_system_built_in, clc$gcs_system_library, clc$gcs_library,
          clc$gcs_catalog, clc$gcs_utility);

  TYPE
    clt$processed_command_stat_data = array [1 .. 1] of sft$counter;

  TYPE
    clt$command_resource_stat_data = array [1 .. 7] of sft$counter;

  TYPE
    clt$search_$system_option = (clc$search_system_library, clc$skip_system_library);

  TYPE
    clt$search_level = (clc$direct_search, clc$indirect_search);

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

  PROCEDURE [XDCL] clp$process_command
    (    block_at_start_of_command: ^clt$block;
         interpreter_mode: clt$interpreter_modes;
         command_from_job_command_file: boolean;
         command_from_execute_command: boolean;
         log_the_command: boolean;
         command_can_be_echoed: boolean;
         parse: clt$parse_state;
     VAR cause_condition {input, output} : clt$when_condition;
     VAR status: ost$status);

?? NEWTITLE := 'command_condition_handler', EJECT ??

{
{ PURPOSE:
{   This condition handler is established to catch any conditions that occur
{   during the processing of a command.  It is also established for "block
{   exit" conditions and since it cannot disestablish itself, it is during the
{   processing of a block exit condition that cleanup activities are performed.
{

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

      VAR
        exit_control_block: ^clt$block,
        ignore_status: ost$status,
        run_time_status: ^ost$status;


      CASE condition.selector OF

      = pmc$block_exit_processing =

{ --- Handle block exit.
        clp$pop_terminated_blocks (block_at_start_of_command, status);

        state.prompting_requested := FALSE;
        IF state.command_log_option = clc$manually_log THEN
          state.command := state.command_reference_text;
          state.command_log_option := clc$automatically_log;
        IFEND;
        IF state.command_block <> NIL THEN
          IF state.command_block^.kind = clc$command_proc_block THEN
            state.command_logging_completed := state.command_logging_completed OR
                  state.command_block^.command_proc_logging_completed;
            state.command_echoing_completed := state.command_echoing_completed OR
                  state.command_block^.command_proc_echoing_completed;
          ELSE
            state.command_logging_completed := state.command_logging_completed OR
                  state.command_block^.command_logging_completed;
            state.command_echoing_completed := state.command_echoing_completed OR
                  state.command_block^.command_echoing_completed;
          IFEND;
        IFEND;
        log_and_or_echo_command (state);

        set_prev_cmnd_name_and_stat (state, status);
        clp$restore_work_area_positions (saved_work_area_positions, state.ignore_status);
        RETURN;

      = mmc$segment_access_condition =

{ --- Handle segment access conditions.

        osp$set_status_from_condition ('CL', condition, save_area, status, state.ignore_status);
        IF (status.condition = cle$work_area_overflow) AND (status.text.size = 0) AND state.found THEN
          osp$append_status_parameter (osc$status_parameter_delimiter, state.name.value, status);
        IFEND;
        EXIT clp$process_command;

      = pmc$system_conditions =

{ --- Handle system (hardware detected) conditions.

        IF pmc$detected_uncorrected_err IN condition.system_conditions THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, state.ignore_status);
        IFEND;
        osp$set_status_from_condition ('CL', condition, save_area, status, state.ignore_status);
        EXIT clp$process_command;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN

{ --- Handle CYBIL run time error.

          run_time_status := condition_information;
          status := run_time_status^;
          EXIT clp$process_command;

        ELSEIF (condition.user_condition_name = clc$exiting_condition) AND (state.command_block <> NIL) AND
              state.command_block^.being_exited 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.

          exit_control_block := condition_information;
          IF #OFFSET (exit_control_block) <> #OFFSET (state.command_block) THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          IFEND;
          EXIT clp$process_command;

        ELSE

{ --- "Continue" any other user defined condition.

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

      ELSE

{ --- "Continue" any other condition.

        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
        RETURN;
      CASEND;

    PROCEND command_condition_handler;
?? TITLE := 'initialize_command_search_state', EJECT ??

    PROCEDURE [INLINE] initialize_command_search_state;

      VAR
        connected_files: ^clt$connected_files,
        ignore_command_list_in_task: boolean;


      clp$find_connected_files (connected_files);

      state.caller_ring := caller_id.ring;
      state.cause_condition := ^cause_condition;

{ Space for state.command PUSHed prior to calling this procedure.

      state.command^ (1, parse.index_limit - parse.unit_index) :=
            parse.text^ (parse.unit_index, parse.index_limit - parse.unit_index);

      state.command_block := NIL;
      state.command_from_execute_command := command_from_execute_command;
      state.command_echoing_activated := connected_files^.echo_count > 0;
      state.command_echoing_completed := NOT (command_can_be_echoed AND state.command_echoing_activated);

      clp$find_command_list (state.command_list, ignore_command_list_in_task);

      state.command_logging_completed := NOT log_the_command;
      state.command_log_option := clc$automatically_log;
      state.command_reference_text := state.command;
      state.data.filler := 0;
      state.data.from_job_command_file := command_from_job_command_file;

{     state.data.generic_source := ;
{     state.data.ordinal := ;
{     state.data.call_method := ;

      state.device_class := rmc$mass_storage_device;

      IF block_at_start_of_command^.use_command_search_mode THEN
        state.effective_search_mode := state.command_list^.search_mode;
      ELSE
        state.effective_search_mode := clc$global_command_search;
      IFEND;

{     state.escaped_command := ;

      state.file.local_file_name := osc$null_name;
      state.file_id := amv$nil_file_identifier;
      state.found := FALSE;
      state.ignore_status.normal := TRUE;
      state.interpreter_mode := interpreter_mode;

{     state.label := ;

      state.library_search_info.command_or_function_module := NIL;
      state.library_search_info.command_or_function_kind := llc$entry_point;
      state.library_search_info.ordinal := 1;
      state.library_search_info.library_privilege := osc$null_name;
      state.library_search_info.module_kind := llc$command_procedure;
      state.library_search_info.log_option := clc$automatically_log;
      state.library_search_info.application_identifier.name := osc$null_name;
      state.name.size := 10;
      state.name.value := 'not_a_name';
      state.nested_commands_can_be_echoed := command_can_be_echoed;
      state.parse := parse;

{     state.path := ;

      state.path_description_obtained := FALSE;

{     state.path_size := ;

      state.prev_cmnd_name_and_stat_set := interpreter_mode <> clc$interpret_mode;

{     state.prompting_requested := ;
{     state.ring_attributes := ;

      state.search_level := clc$direct_search;

{     state.search_name := ;
{     state.separator := ;

      state.source.index := parse.unit_index;
      state.source.size := parse.index_limit - parse.unit_index;

      state.work_area := work_area;

    PROCEND initialize_command_search_state;
?? OLDTITLE, EJECT ??

    CONST
      invalid_command_attempted = ' User attempted to access a command that is not allowed.' CAT
            '  The job is being terminated.';

    VAR
      caller_id: ost$caller_identifier,
      command_reference_parse: clt$parse_state,
      command_resource_data: clt$command_resource_stat_data,
      command_statistics_enabled: boolean,
      command_table_index: clt$command_table_index,
      control_statement_descriptor: ^clt$control_statement_desc,
      empty_command: boolean,
      form: clt$command_reference_form,
      ignore_secure_logging_activated: boolean,
      job_attribute_results: ^jmt$job_attribute_results,
      log_secure_parameters: boolean,
      restricted_mainframe: boolean,
      saved_work_area_positions: clt$saved_work_area_positions,
      state: clt$command_search_state,
      statistics_after_processing: clt$command_resource_statistics,
      statistics_before_processing: clt$command_resource_statistics,
      utility_command_list_entry: ^clt$command_list_entry,
      work_area: ^^clt$work_area;

    clp$get_command_statistics (statistics_before_processing, ignore_secure_logging_activated,
          command_statistics_enabled);

    #CALLER_ID (caller_id);

    clp$get_work_area (#RING (^work_area), work_area, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$save_work_area_positions (saved_work_area_positions);

    PUSH state.command: [parse.index_limit - parse.unit_index];
    initialize_command_search_state;

    osp$establish_condition_handler (^command_condition_handler, TRUE);

  /process_command/
    BEGIN
      clp$parse_command (state.parse, state.prompting_requested, state.escaped_command, state.label,
            command_reference_parse, state.file, form, state.name, utility_command_list_entry,
            state.separator, empty_command, status);
      state.search_name := state.name;

      CASE state.interpreter_mode OF
      = clc$interpret_mode =
        IF NOT status.normal THEN
          EXIT /process_command/;
        ELSEIF empty_command THEN
          state.prev_cmnd_name_and_stat_set := TRUE;
          #SPOIL (state.prev_cmnd_name_and_stat_set);
          EXIT /process_command/;
        IFEND;
      = clc$skip_mode =
        IF (NOT status.normal) OR empty_command THEN
          status.normal := TRUE;
          EXIT /process_command/;
        IFEND;
      = clc$help_mode =
        IF NOT status.normal THEN
          EXIT /process_command/;
        ELSEIF empty_command OR (state.label <> osc$null_name) THEN
          osp$set_status_abnormal ('CL', cle$expecting_command, state.command^, status);
          EXIT /process_command/;
        IFEND;
      ELSE
        ;
      CASEND;

      state.source.reference_index := command_reference_parse.unit_index;
      state.source.reference_size := command_reference_parse.index_limit - state.source.reference_index;
      state.command_reference_text := ^state.command^ (state.source.reference_index - state.source.index + 1,
            state.source.reference_size);
      state.source.ordinal := 1;
      state.source.function_interface := clc$fi_contemporary;

      clp$get_log_secure_parameters (log_secure_parameters);

      IF state.separator = clc$lex_equal THEN
        set_control_statement_logging (state);
        log_and_or_echo_command (state);
        IF state.source.reference_size = 0 THEN
          process_case_selection (state, status);
        ELSEIF state.interpreter_mode = clc$interpret_mode THEN
          process_assignment (command_reference_parse, state, status);
        IFEND;
      ELSEIF form <> clc$name_only_command_ref THEN
        clp$check_name_for_control (state.name, control_statement_descriptor);
        IF (state.interpreter_mode <> clc$skip_mode) OR ((control_statement_descriptor <> NIL) AND
              (control_statement_descriptor^.call_in_skip_mode)) THEN
          IF ((state.caller_ring > osc$tsrv_ring) AND (state.effective_search_mode =
                clc$exclusive_command_search)) OR state.escaped_command THEN
            osp$set_status_abnormal ('CL', cle$file_dot_cmnd_not_allowed, state.command_reference_text^,
                  status);

            { A requirement for the China Weather systems states that if a user in the PRODUCTION job class
            { attempts to execute a command that they are not allowed to execute, the system should log the
            { attempt and terminate the job.

            osp$check_for_desired_mf_class (osc$mc_china_class, restricted_mainframe);
            IF restricted_mainframe THEN
              PUSH job_attribute_results: [1 .. 1];
              job_attribute_results^ [1].key := jmc$job_class;
              jmp$get_job_attributes (job_attribute_results, state.ignore_status);
              IF job_attribute_results^ [1].job_class = 'PRODUCTION' THEN
                pmp$log_ascii (invalid_command_attempted, $pmt$ascii_logset [pmc$system_log, pmc$job_log],
                      pmc$msg_origin_system, state.ignore_status);
                jmp$logout (state.ignore_status);
              IFEND;
            IFEND;
            RETURN;
          IFEND;
          CASE form OF
          = clc$file_cycle_command_ref =
            process_command_file (state, status);
            IF status.normal AND (NOT state.found) THEN
              osp$set_status_abnormal ('CL', cle$unknown_command, state.name.value, status);
              IF NOT log_secure_parameters THEN
                state.command := state.command_reference_text;
              IFEND;
            IFEND;
          = clc$module_or_file_command_ref =
            process_command_in_file (log_secure_parameters, state, status);
          = clc$system_command_ref =
            state.source.kind := clc$system_commands;
            process_system_command (clc$search_system_library, state, status);
            IF status.normal AND (NOT state.found) THEN
              osp$set_status_abnormal ('CL', cle$unknown_command, state.name.value, status);
              IF NOT log_secure_parameters THEN
                state.command := state.command_reference_text;
              IFEND;
            IFEND;
          = clc$utility_command_ref =
            state.data.generic_source := clc$gcs_utility;
            state.source.kind := clc$sub_commands;
            state.source.utility_name := utility_command_list_entry^.utility_name;
            state.source.utility_info := utility_command_list_entry^.utility_info;
            process_sub_command (state, NIL, status);
            IF status.normal AND (NOT state.found) THEN
              osp$set_status_abnormal ('CL', cle$unknown_command, state.name.value, status);
              IF NOT log_secure_parameters THEN
                state.command := state.command_reference_text;
              IFEND;
            IFEND;
          ELSE
            ;
          CASEND;
        IFEND;
      ELSE
        clp$check_name_for_control (state.name, control_statement_descriptor);
        IF control_statement_descriptor <> NIL THEN
          IF (state.interpreter_mode <> clc$skip_mode) OR control_statement_descriptor^.call_in_skip_mode THEN
            IF control_statement_descriptor^.kind = clc$control_statement THEN
              process_control_statement (state, control_statement_descriptor^.label_allowed,
                    control_statement_descriptor^.statement, status);
            ELSE
              process_control_command (state, control_statement_descriptor^.command, status);
            IFEND;
          ELSEIF control_statement_descriptor^.kind = clc$control_statement THEN
            set_control_statement_logging (state);
          IFEND;
        ELSEIF state.interpreter_mode = clc$skip_mode THEN
          IF (block_at_start_of_command^.kind = clc$input_block) AND
                block_at_start_of_command^.being_exited AND (block_at_start_of_command^.associated_utility <>
                NIL) AND (block_at_start_of_command^.associated_utility^.command_environment.commands <> NIL)
                THEN
            clp$search_command_table (state.name.value, block_at_start_of_command^.associated_utility^.
                  command_environment.commands, command_table_index, state.found);
            IF state.found AND (block_at_start_of_command^.associated_utility^.command_environment.
                  commands^ [command_table_index].ordinal = block_at_start_of_command^.associated_utility^.
                  command_environment.termination_command_ordinal) THEN
              clp$ignore_rest_of_file (block_at_start_of_command^.label, status);
            IFEND;
          IFEND;
        ELSE
          process_command_in_list (log_secure_parameters, state, status);
        IFEND;
      IFEND;

      IF (state.interpreter_mode = clc$interpret_mode) AND command_statistics_enabled THEN
        clp$get_command_statistics (statistics_after_processing, ignore_secure_logging_activated,
              command_statistics_enabled);
        IF command_statistics_enabled THEN
          calculate_command_statistics (statistics_before_processing, statistics_after_processing,
                command_resource_data);
          sfp$emit_statistic (cll$command_resources, state.name.value, ^command_resource_data,
                state.ignore_status);
        IFEND;
      IFEND;
    END /process_command/;

    state.prompting_requested := FALSE;
    IF state.command_log_option = clc$manually_log THEN
      state.command := state.command_reference_text;
      state.command_log_option := clc$automatically_log;
    IFEND;
    log_and_or_echo_command (state);

    set_prev_cmnd_name_and_stat (state, status);

    clp$restore_work_area_positions (saved_work_area_positions, state.ignore_status);

    osp$disestablish_cond_handler;

  PROCEND clp$process_command;
?? TITLE := 'verify_prompting_requested', EJECT ??

  PROCEDURE [INLINE] verify_prompting_requested
    (    prompting_requested: boolean;
     VAR status: ost$status);

    VAR
      job_mode: jmt$job_mode;

    IF prompting_requested THEN
      job_mode := pmf$job_mode ();
      IF (job_mode = jmc$batch) AND (NOT jmp$system_job ()) THEN
        osp$set_status_abnormal ('CL', ife$current_job_not_interactive, 'Prompting Statement', status);
      IFEND;
    IFEND;

  PROCEND verify_prompting_requested;
?? TITLE := '[inline] calculate_command_statistics', EJECT ??

  PROCEDURE [inline] calculate_command_statistics
    (    statistics_before_processing: clt$command_resource_statistics;
         statistics_after_processing: clt$command_resource_statistics;
     VAR command_resource_data: clt$command_resource_stat_data);

    command_resource_data [1] := statistics_after_processing.cptime.task_time -
          statistics_before_processing.cptime.task_time;
    command_resource_data [2] := statistics_after_processing.cptime.monitor_time -
          statistics_before_processing.cptime.monitor_time;
    command_resource_data [3] := statistics_after_processing.paging_statistics.page_fault_count -
          statistics_before_processing.paging_statistics.page_fault_count;
    command_resource_data [4] := statistics_after_processing.paging_statistics.page_in_count -
          statistics_before_processing.paging_statistics.page_in_count;
    command_resource_data [5] := statistics_after_processing.paging_statistics.pages_reclaimed_from_queue -
          statistics_before_processing.paging_statistics.pages_reclaimed_from_queue;
    command_resource_data [6] := statistics_after_processing.paging_statistics.new_pages_assigned -
          statistics_before_processing.paging_statistics.new_pages_assigned;
    command_resource_data [7] := statistics_after_processing.paging_statistics.pages_from_server -
          statistics_before_processing.paging_statistics.pages_from_server;

  PROCEND calculate_command_statistics;
?? TITLE := 'emit_processed_command_stat', EJECT ??

  PROCEDURE [INLINE] emit_processed_command_stat
    (VAR state {input, output} : clt$command_search_state);

    VAR
      audit_information: sft$audit_information,
      dummy_status: ost$status,
      processed_command_stat_data: clt$processed_command_stat_data;


    #UNCHECKED_CONVERSION (state.data, processed_command_stat_data);
    sfp$emit_statistic (cll$processed_command, state.name.value, ^processed_command_stat_data,
          state.ignore_status);

{ Emit the processed command audit statistic.

    ?IF NOT clc$compiling_for_test_harness THEN
      audit_information.audited_operation := sfc$ao_job_process_command;
      audit_information.process_command.command_name_p := ^state.name.value;
      IF state.data.from_job_command_file THEN
        audit_information.process_command.command_source := sfc$cs_primary_command_file;
      ELSE
        audit_information.process_command.command_source := sfc$cs_secondary_command_file;
      IFEND;
      audit_information.process_command.command_call_method := state.data.call_method;
      dummy_status.normal := TRUE;
      sfp$emit_audit_statistic (audit_information, dummy_status);
    ?IFEND

  PROCEND emit_processed_command_stat;
?? TITLE := 'process_pt_request', EJECT ??

  PROCEDURE process_pt_request
    (    work_list: bat$process_pt_work_list;
         local_file_name: amt$local_file_name;
     VAR evaluated_file_reference: {i/o} fst$evaluated_file_reference;
     VAR process_pt_results: bat$process_pt_results;
     VAR status: ost$status);

    VAR
      context: ^ost$ecp_exception_context;

    PUSH context;
    context^ := osv$initial_exception_context;
    context^.file.selector := osc$ecp_evaluated_file_ref;
    context^.file.evaluated_file_reference := evaluated_file_reference;
    REPEAT
      context^.condition_status := status;
      osp$enforce_exception_policies (context^);
      status := context^.condition_status;

      IF (NOT osp$file_access_condition (status)) OR (NOT context^.wait) THEN
        RETURN;
      ELSE
        bap$process_pt_request (work_list, local_file_name, evaluated_file_reference, process_pt_results,
              status);
      IFEND;
    UNTIL status.normal;

  PROCEND process_pt_request;
?? TITLE := 'set_control_statement_logging', EJECT ??

  PROCEDURE [INLINE] set_control_statement_logging
    (VAR state {input, output} : clt$command_search_state);

    VAR
      ignore_block_in_current_task: boolean,
      utility_block: ^clt$block;


    IF NOT state.command_logging_completed THEN
      clp$find_utility_block (osc$null_name, utility_block, ignore_block_in_current_task);
      IF (utility_block <> NIL) AND (NOT utility_block^.command_environment.subcommand_logging_enabled) THEN
        state.command_logging_completed := TRUE;
      IFEND;
    IFEND;

  PROCEND set_control_statement_logging;
?? TITLE := 'log_and_or_echo_command', EJECT ??

  PROCEDURE [INLINE] log_and_or_echo_command
    (VAR state {input, output} : clt$command_search_state);


    IF (NOT state.command_logging_completed) AND (state.command_log_option = clc$automatically_log) AND
         (NOT state.prompting_requested) THEN
      clp$log_command_line (state.command^, state.ignore_status);
      state.command_logging_completed := TRUE;
    IFEND;

    IF (NOT state.command_echoing_completed) AND (state.command_log_option = clc$automatically_log) THEN
      clp$echo_command (state.interpreter_mode, state.command^, state.ignore_status);
      state.command_echoing_completed := TRUE;
    IFEND;

  PROCEND log_and_or_echo_command;
?? TITLE := 'initialize_application_info', EJECT ??

  PROCEDURE [INLINE] initialize_application_info
    (VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);


    status.normal := TRUE;

    IF (state.library_search_info.application_identifier.name <> osc$null_name) AND
          (state.interpreter_mode = clc$interpret_mode) THEN
      clp$initialize_application_info (state.library_search_info.application_identifier,
            state.library_search_info.library_privilege, state.library_search_info.module_kind, status);
    IFEND;

  PROCEND initialize_application_info;
?? TITLE := 'set_prev_cmnd_name_and_stat', EJECT ??

  PROCEDURE [INLINE] set_prev_cmnd_name_and_stat
    (VAR state {input, output} : clt$command_search_state;
     VAR status {input} : ost$status);


    IF NOT state.prev_cmnd_name_and_stat_set THEN
      IF NOT state.command_from_execute_command THEN
        clp$set_prev_cmnd_name_and_stat (state.command, state.name.value, status);
      IFEND;
      state.prev_cmnd_name_and_stat_set := TRUE;
    IFEND;

  PROCEND set_prev_cmnd_name_and_stat;
?? TITLE := 'process_assignment', EJECT ??

  PROCEDURE [INLINE] process_assignment
    (VAR variable_parse {input, output} : clt$parse_state;
     VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);


    IF state.escaped_command THEN
      osp$set_status_abnormal ('CL', cle$unexpected_escape, state.name.value, status);
    ELSEIF state.label <> osc$null_name THEN
      osp$set_status_abnormal ('CL', cle$assignment_cant_be_labelled, '', status);
    ELSEIF state.prompting_requested THEN
      osp$set_status_abnormal ('CL', cle$unexpected_prompt_statement, state.name.value, status);
    ELSEIF state.command_from_execute_command THEN
      osp$set_status_abnormal ('CL', cle$invalid_exec_command, state.name.value, status);
    ELSE
      sfp$emit_statistic (cll$processed_control_statement, state.name.value, NIL, state.ignore_status);

      clp$assignment_statement (variable_parse, state.parse, state.work_area^, status);
    IFEND;

  PROCEND process_assignment;
?? TITLE := 'process_case_selection', EJECT ??

  PROCEDURE [INLINE] process_case_selection
    (VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);


    IF state.escaped_command THEN
      osp$set_status_abnormal ('CL', cle$unexpected_escape, state.name.value, status);
    ELSEIF state.label <> osc$null_name THEN
      osp$set_status_abnormal ('CL', cle$case_sel_cant_be_labelled, '', status);
    ELSEIF state.prompting_requested THEN
      osp$set_status_abnormal ('CL', cle$unexpected_prompt_statement, state.name.value, status);
    ELSEIF state.command_from_execute_command THEN
      osp$set_status_abnormal ('CL', cle$invalid_exec_command, state.name.value, status);
    ELSE
      sfp$emit_statistic (cll$processed_control_statement, state.name.value, NIL, state.ignore_status);

      clp$case_selection_statement (state.interpreter_mode, state.parse, state.work_area^, status);
    IFEND;

  PROCEND process_case_selection;
?? TITLE := 'process_control_command', EJECT ??

  PROCEDURE [INLINE] process_control_command
    (VAR state {input, output} : clt$command_search_state;
         command: clt$command;
     VAR status: ost$status);


    IF state.label <> osc$null_name THEN
      osp$set_status_abnormal ('CL', cle$commands_cant_be_labelled, '', status);
    ELSE
      verify_prompting_requested (state.prompting_requested, status);
      IF status.normal THEN
        IF state.command_from_execute_command THEN
          osp$set_status_abnormal ('CL', cle$invalid_exec_command, state.name.value, status);
        ELSE
          state.data.generic_source := clc$gcs_system_built_in;
          state.source.kind := clc$system_commands;
          state.source.system_command_table := clv$intrinsic_commands;
          process_sub_command (state, clv$intrinsic_commands, status);

{ It is assumed that every "control command" has a corresponding entry in the
{ clv$intrinsic_commands.  If this turns out not to be true, call the command
{ anyway.  Certain things will not work for such a command--like the display_
{ command_information command, and the ability to determine the source of the
{ command (the $source function, etc.).

          IF NOT state.found THEN
            invoke_sub_command (state, command, status);
          IFEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND process_control_command;
?? TITLE := 'process_control_statement', EJECT ??

  PROCEDURE [INLINE] process_control_statement
    (VAR state {input, output} : clt$command_search_state;
         label_allowed: boolean;
         statement: clt$control_statement;
     VAR status: ost$status);

    VAR
      info: clt$control_statement_info;


    info.interpreter_mode := state.interpreter_mode;
    info.label := state.label;
    info.logging_required := NOT state.command_logging_completed;
    info.echoing_required := NOT state.command_echoing_completed;

    set_control_statement_logging (state);
    log_and_or_echo_command (state);

    IF state.interpreter_mode = clc$help_mode THEN
      osp$set_status_abnormal ('CL', cle$expecting_command, state.command^, status);
    ELSEIF (state.label <> osc$null_name) AND (NOT label_allowed) THEN
      osp$set_status_abnormal ('CL', cle$statement_cant_be_labelled, state.name.value, status);
    ELSEIF state.escaped_command THEN
      osp$set_status_abnormal ('CL', cle$unexpected_escape, state.name.value, status);
    ELSEIF state.separator = clc$lex_comma THEN
      osp$set_status_abnormal ('CL', cle$unexpected_comma_after, state.name.value, status);
    ELSEIF state.prompting_requested THEN
      osp$set_status_abnormal ('CL', cle$unexpected_prompt_statement, state.name.value, status);
    ELSEIF state.command_from_execute_command THEN
      osp$set_status_abnormal ('CL', cle$invalid_exec_command, state.name.value, status);
    ELSE
      sfp$emit_statistic (cll$processed_control_statement, state.name.value, NIL, state.ignore_status);

      statement^ (info, state.parse, state.work_area^, state.cause_condition^, status);
    IFEND;

  PROCEND process_control_statement;
?? TITLE := 'process_command_in_list', EJECT ??

  PROCEDURE process_command_in_list
    (    log_secure_parameters: boolean;
     VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

    VAR
      current_entry: ^clt$command_list_entry,
      entry_after_fence: ^clt$command_list_entry,
      ignore_path_handle: fmt$path_handle,
      search_status: ^ost$status,
      system_commands_searched: boolean,
      working_catalog: ^^clt$working_catalog;


    status.normal := TRUE;
    search_status := NIL;

    IF state.escaped_command THEN
      IF state.effective_search_mode = clc$exclusive_command_search THEN
        osp$set_status_abnormal ('CL', cle$escape_not_allowed, '', status);
        RETURN;
      IFEND;
    IFEND;
    IF state.label <> osc$null_name THEN
      osp$set_status_abnormal ('CL', cle$commands_cant_be_labelled, '', status);
      RETURN;
    IFEND;
    verify_prompting_requested (state.prompting_requested, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF state.escaped_command THEN
      current_entry := state.command_list^.entries.entry_after_fence;
      entry_after_fence := NIL;
    ELSEIF state.effective_search_mode <> clc$global_command_search THEN
      current_entry := state.command_list^.entries.first_entry;
      entry_after_fence := state.command_list^.entries.entry_after_fence;
    ELSE
      current_entry := state.command_list^.entries.first_entry;
      entry_after_fence := NIL;
    IFEND;

    system_commands_searched := FALSE;

    WHILE current_entry <> entry_after_fence DO
      state.path_description_obtained := FALSE;
      state.source.kind := current_entry^.kind;
      CASE current_entry^.kind OF

      = clc$catalog_commands =
        state.source.local_file_name := current_entry^.local_file_name;
        clp$get_fs_path_string (current_entry^.local_file_name, state.path, state.path_size,
              ignore_path_handle, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        state.path_description_obtained := TRUE;
        process_command_in_catalog (state, status);

      = clc$working_catalog_commands =
        clp$find_working_catalog (working_catalog);
        state.source.local_file_name := working_catalog^^.handle;
        clp$convert_file_ref_to_string (working_catalog^^.evaluated_file_reference, FALSE, state.path,
              state.path_size, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        state.path_description_obtained := TRUE;
        process_command_in_catalog (state, status);

      = clc$library_commands =
        IF current_entry^.library_contains.commands THEN
          state.file.local_file_name := current_entry^.local_file_name;
          state.source.local_file_name := current_entry^.local_file_name;
          process_command_in_library (TRUE, state, status);
        IFEND;

      = clc$system_commands =
        state.source.system_command_table := NIL;
        process_system_command (clc$search_system_library, state, status);
        system_commands_searched := TRUE;

      = clc$sub_commands =
        state.data.generic_source := clc$gcs_utility;
        state.source.utility_name := current_entry^.utility_name;
        state.source.utility_info := current_entry^.utility_info;
        process_sub_command (state, NIL, status);
        IF (NOT status.normal) AND (status.condition = cle$util_cmds_fctns_unavailable) AND
              (status.text.value (2, status.text.size-1) = state.name.value (1, state.name.size)) THEN
          IF search_status = NIL THEN
            PUSH search_status;
            search_status^ := status;
          IFEND;
          status.normal := TRUE;
          state.found := FALSE;
        IFEND;

      ELSE
        ;
      CASEND;

      IF (NOT status.normal) OR state.found THEN
        RETURN;
      IFEND;

      current_entry := current_entry^.next_entry;
    WHILEND;

    IF NOT system_commands_searched THEN
      state.data.generic_source := clc$gcs_system_built_in;
      state.source.kind := clc$system_commands;
      state.source.system_command_table := clv$intrinsic_commands;
      process_sub_command (state, clv$intrinsic_commands, status);
      IF (NOT status.normal) OR state.found THEN
        RETURN;
      IFEND;
    IFEND;

    ?IF fsc$compiling_for_test_harness AND clc$compiling_for_test_harness THEN
      state.data.generic_source := clc$gcs_system_built_in;
      state.source.kind := clc$system_commands;
      state.source.system_command_table := fsv$test_harness_cmnds;
      process_sub_command (state, fsv$test_harness_cmnds, status);
      IF (NOT status.normal) OR state.found THEN
        RETURN;
      IFEND;
    ?IFEND

    IF search_status = NIL THEN
      osp$set_status_abnormal ('CL', cle$unknown_command, state.name.value, status);
      IF NOT log_secure_parameters THEN
        state.command := state.command_reference_text;
      IFEND;
    ELSE
      status := search_status^;
    IFEND;

  PROCEND process_command_in_list;
?? TITLE := 'process_command_in_file', EJECT ??

  PROCEDURE process_command_in_file
    (    log_secure_parameters: boolean;
     VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

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

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

      VAR
        ignore_status: ost$status;


      IF state.found THEN
        clp$close_command_library (state.file.local_file_name, ignore_status);
      IFEND;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    VAR
      ignore_path_handle: fmt$path_handle;


    status.normal := TRUE;

    IF state.label <> osc$null_name THEN
      osp$set_status_abnormal ('CL', cle$commands_cant_be_labelled, '', status);
      RETURN;
    IFEND;
    verify_prompting_requested (state.prompting_requested, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$get_fs_path_string (state.file.local_file_name, state.path, state.path_size, ignore_path_handle,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    state.path_description_obtained := TRUE;

    IF state.path (1, 8) = ':$LOCAL ' THEN
      state.source.kind := clc$catalog_commands;
      state.source.local_file_name := state.file.local_file_name;
      process_command_in_catalog (state, status);
    ELSE
      state.source.kind := clc$library_commands;
      state.source.local_file_name := state.file.local_file_name;
      state.found := FALSE;
      #SPOIL (state.found);

      osp$establish_block_exit_hndlr (^abort_handler);
      process_command_in_library (FALSE, state, status);
      osp$disestablish_cond_handler;
    IFEND;

    IF status.normal AND (NOT state.found) THEN
      osp$set_status_abnormal ('CL', cle$unknown_command, state.name.value, status);
      IF NOT log_secure_parameters THEN
        state.command := state.command_reference_text;
      IFEND;
    IFEND;

  PROCEND process_command_in_file;
?? TITLE := 'process_command_in_catalog', EJECT ??

  PROCEDURE process_command_in_catalog
    (VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

    VAR
      command_path_name: fst$path,
      evaluated_file_reference: fst$evaluated_file_reference,
      local_status: ost$status,
      path_handle_name: fst$path_handle_name,
      pt_results: bat$process_pt_results,
      work_list: bat$process_pt_work_list;


    status.normal := TRUE;
    state.data.generic_source := clc$gcs_catalog;
    state.data.ordinal := 1;
    state.source.ordinal := 1;

    IF state.source.local_file_name = clv$local_catalog_handle_name THEN
      evaluated_file_reference := fsv$evaluated_file_reference;
      evaluated_file_reference.path_structure (1) := $CHAR (6);
      evaluated_file_reference.path_structure (2, 6) := '$LOCAL';
      evaluated_file_reference.path_structure (8) := $CHAR (state.name.size);
      evaluated_file_reference.path_structure (9, state.name.size) := state.name.value;
      evaluated_file_reference.path_structure_size := state.name.size + 8;
      evaluated_file_reference.number_of_path_elements := 2;
      evaluated_file_reference.path_resolution := fsc$unresolved_path;

      work_list := $bat$process_pt_work_list [bac$resolve_path];
      bap$process_pt_request (work_list, osc$null_name, evaluated_file_reference, pt_results, status);
      IF (NOT status.normal) AND osp$file_access_condition (status) THEN
        process_pt_request (work_list, osc$null_name, evaluated_file_reference, pt_results, status);
      IFEND;
      IF (NOT status.normal) OR NOT (bac$cycle_description_exists IN pt_results) THEN
        status.normal := TRUE;
        RETURN;
      IFEND;
      clp$construct_path_handle_name (evaluated_file_reference.path_handle_info.path_handle,
            state.file.local_file_name);

    ELSE
      IF (state.path_size + 1 + state.name.size) > fsc$max_path_size THEN
        osp$set_status_abnormal ('CL', cle$file_reference_too_long, '', status);
        RETURN;
      IFEND;
      command_path_name := state.path (1, state.path_size);
      command_path_name (state.path_size + 1) := '.';
      command_path_name (state.path_size + 2, state.name.size) := state.name.value (1, state.name.size);

{     clp$convert_str_to_path_handle (command_path_name (1, state.path_size + 1 + state.name.size), TRUE,

      clp$convert_str_to_path_handle (command_path_name (1, state.path_size + 1 + state.name.size), FALSE,
            FALSE, FALSE, state.file.local_file_name, evaluated_file_reference, status);
      IF NOT status.normal THEN
        status.normal := TRUE;
        RETURN;
      IFEND;
    IFEND;

    process_command_file (state, status);

  PROCEND process_command_in_catalog;
?? TITLE := 'process_command_file', EJECT ??

  PROCEDURE process_command_file
    (VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

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

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

      VAR
        ignore_status: ost$status;


      clp$close_command_file (state.file_id, opened_executable_file, ignore_status);

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    VAR
      close_status: ost$status,
      file_contents: clt$file_contents,
      opened_executable_file: boolean,
      ignore_file_has_fap: boolean,
      ignore_segment: ^SEQ ( * ),
      line_layout: clt$line_layout,
      nested_commands_can_be_echoed: boolean,
      object_file_list: ^pmt$object_file_list,
      path_handle_name: fst$path_handle_name,
      program_description: ^pmt$program_description,
      program_attributes: ^pmt$program_attributes;


    state.file_id := amv$nil_file_identifier;
    #SPOIL (state.file_id);
    osp$establish_block_exit_hndlr (^abort_handler);

    clp$access_command_file (clc$catalog_command, state.caller_ring, state.file.local_file_name,
          state.file_id, ignore_segment, opened_executable_file, nested_commands_can_be_echoed, line_layout,
          file_contents, state.ring_attributes, ignore_file_has_fap, state.device_class, path_handle_name,
          status);
    IF file_contents.path_exists AND (NOT file_contents.is_object) AND
          (path_handle_name <> osc$null_name) THEN
      state.file.local_file_name := path_handle_name;
    IFEND;

    IF NOT status.normal THEN
      IF status.condition = cle$not_a_command_file THEN
        status.normal := TRUE;
      IFEND;
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

    state.found := TRUE;
    state.source.kind := clc$catalog_commands;
    state.command_log_option := clc$automatically_log;
    state.nested_commands_can_be_echoed := state.nested_commands_can_be_echoed AND
          nested_commands_can_be_echoed;

    IF file_contents.is_object THEN
      PUSH program_description: [[pmt$program_attributes, REP 1 OF amt$local_file_name]];
      RESET program_description;
      NEXT program_attributes IN program_description;
      program_attributes^.contents := $pmt$prog_description_contents [pmc$object_file_list_specified];
      program_attributes^.number_of_object_files := 1;
      NEXT object_file_list: [1 .. 1] IN program_description;
      object_file_list^ [1] := state.file.local_file_name;
      invoke_program_command (state, NIL, program_description, status);
    ELSE
      state.library_search_info.command_or_function_module := NIL;
      invoke_scl_procedure (state, line_layout, status);
      clp$close_command_file (state.file_id, opened_executable_file, close_status);
      IF status.normal AND (NOT close_status.normal) THEN
        status := close_status;
      IFEND;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND process_command_file;
?? TITLE := 'process_command_in_library', EJECT ??

  PROCEDURE [INLINE] process_command_in_library
    (    searching_command_list: boolean;
     VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

    VAR
      context: ^ost$ecp_exception_context,
      ignore_path_handle: fmt$path_handle,
      ignore_path_size: fst$path_size,
      local_status: ost$status,
      nested_commands_can_be_echoed: boolean,
      saved_status: ^ost$status;


    status.normal := TRUE;
    context := NIL;
    saved_status := NIL;

    IF state.file.local_file_name = osc$null_name THEN
      state.data.generic_source := clc$gcs_system_library;
    ELSE
      state.data.generic_source := clc$gcs_library;
    IFEND;

    REPEAT
      clp$search_command_library (state.search_name.value, clc$command, searching_command_list,
            state.work_area^, state.file.local_file_name, state.file_id, state.ring_attributes,
            nested_commands_can_be_echoed, state.library_search_info, state.found, 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 := ^state.file.local_file_name;
        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);
    IF status.normal THEN
      IF state.found THEN
        state.command_log_option := state.library_search_info.log_option;
        state.nested_commands_can_be_echoed := state.nested_commands_can_be_echoed AND
              nested_commands_can_be_echoed;
        IF state.search_level = clc$direct_search THEN
          state.source.ordinal := state.library_search_info.ordinal;
          IF state.source.kind = clc$library_commands THEN
            state.source.local_file_name := state.file.local_file_name;
          IFEND;
        IFEND;
        invoke_command_in_library (state, state.search_name.value, FALSE, status);
      IFEND;

      REPEAT
        clp$close_command_library (state.file.local_file_name, local_status);
        IF NOT local_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 := ^state.file.local_file_name;
          IFEND;
          context^.condition_status := local_status;
          osp$enforce_exception_policies (context^);
          local_status := context^.condition_status;
        IFEND;
      UNTIL local_status.normal OR (NOT osp$file_access_condition (local_status)) OR
            (NOT context^.wait);
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;

    ELSEIF searching_command_list THEN
      RETURN;

    ELSEIF (status.condition = pfe$path_too_short) OR (status.condition = pfe$name_not_permanent_file) OR
          (status.condition = pfe$unknown_permanent_file) OR (status.condition = ame$file_not_known) THEN

{ !!! KLUDGE !!! This can be removed when CATALOG_NAME_SECURITY is fixed.

      IF (status.condition = pfe$unknown_permanent_file) OR (status.condition = ame$file_not_known) THEN
        PUSH saved_status;
        saved_status^ := status;
      IFEND;

      status.normal := TRUE;
      IF NOT state.path_description_obtained THEN
        clp$get_fs_path_string (state.file.local_file_name, state.path, ignore_path_size, ignore_path_handle,
              status);
      IFEND;

      IF status.normal THEN
        state.path_description_obtained := TRUE;
        process_command_in_catalog (state, status);

{ !!! KLUDGE !!! This can be removed when CATALOG_NAME_SECURITY is fixed.

        IF (NOT status.normal) AND (saved_status <> NIL) THEN
          status := saved_status^;
        IFEND;
      IFEND;

    ELSE
      REPEAT
        clp$close_command_library (state.file.local_file_name, local_status);
        IF NOT local_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 := ^state.file.local_file_name;
          IFEND;
          context^.condition_status := local_status;
          osp$enforce_exception_policies (context^);
          local_status := context^.condition_status;
        IFEND;
      UNTIL local_status.normal OR (NOT osp$file_access_condition (local_status)) OR
            (NOT context^.wait);
    IFEND;

  PROCEND process_command_in_library;
?? TITLE := 'process_command_in_utility_lib', EJECT ??

  PROCEDURE process_command_in_utility_lib
    (VAR state {input, output} : clt$command_search_state;
         processor_name: pmt$program_name;
     VAR status: ost$status);

    VAR
      context: ^ost$ecp_exception_context,
      found_command: boolean,
      index: integer,
      local_file_name: amt$local_file_name,
      nested_commands_can_be_echoed: boolean;


    context := NIL;
    state.data.generic_source := clc$gcs_library;

    FOR index := 1 TO UPPERBOUND (state.source.utility_info^.libraries^) DO
      local_file_name := state.source.utility_info^.libraries^ [index];
      REPEAT
        clp$search_command_library (processor_name, clc$command, FALSE, state.work_area^, local_file_name,
              state.file_id, state.ring_attributes, nested_commands_can_be_echoed, state.library_search_info,
              found_command, 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 := ^local_file_name;
          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);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF found_command THEN
        state.file.local_file_name := state.source.utility_info^.libraries^ [index];
        state.command_log_option := state.library_search_info.log_option;
        state.nested_commands_can_be_echoed := state.nested_commands_can_be_echoed AND
              nested_commands_can_be_echoed;
        invoke_command_in_library (state, processor_name, FALSE, status);
        RETURN;
      IFEND;
    FOREND;

    osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);

  PROCEND process_command_in_utility_lib;
?? TITLE := 'process_command_in_aux_library', EJECT ??

  PROCEDURE process_command_in_aux_library
    (VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

    VAR
      context: ^ost$ecp_exception_context,
      index: integer,
      local_file_name: amt$local_file_name,
      nested_commands_can_be_echoed: boolean;


    context := NIL;
    state.data.generic_source := clc$gcs_library;

    FOR index := 1 TO UPPERBOUND (state.source.utility_info^.auxiliary_libraries^) DO
      IF state.source.utility_info^.auxiliary_libraries^ [index].contains.commands THEN
        local_file_name := state.source.utility_info^.auxiliary_libraries^ [index].name;
        REPEAT
          clp$search_command_library (state.search_name.value, clc$command, FALSE, state.work_area^,
                local_file_name, state.file_id, state.ring_attributes, nested_commands_can_be_echoed,
                state.library_search_info, state.found, 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 := ^local_file_name;
            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);
        IF NOT status.normal THEN
          status.normal := TRUE;
        ELSEIF state.found THEN
          state.file.local_file_name := state.source.utility_info^.auxiliary_libraries^ [index].name;
          state.source.kind := clc$library_commands;
          state.source.local_file_name := state.source.utility_info^.auxiliary_libraries^ [index].name;
          state.source.ordinal := state.library_search_info.ordinal;
          state.command_log_option := state.library_search_info.log_option;
          state.command_logging_completed := TRUE;
          state.nested_commands_can_be_echoed := state.nested_commands_can_be_echoed AND
                nested_commands_can_be_echoed;
          invoke_command_in_library (state, state.search_name.value, FALSE, status);
          RETURN;
        IFEND;
      IFEND;
    FOREND;

  PROCEND process_command_in_aux_library;
?? TITLE := 'process_sub_command', EJECT ??

  PROCEDURE process_sub_command
    (VAR state {input, output} : clt$command_search_state;
         built_in_command_table: ^clt$command_table;
     VAR status: ost$status);

    VAR
      command_table: ^clt$command_table,
      context: ^ost$ecp_exception_context,
      current_task_id: pmt$task_id,
      entry_index: clt$command_table_index,
      loaded_address: pmt$loaded_address,
      loaded_command: clt$command;


    status.normal := TRUE;
    context := NIL;

    IF built_in_command_table = NIL THEN
      command_table := state.source.utility_info^.commands;
      state.source.auxilliary_table := FALSE;
    ELSE
      command_table := built_in_command_table;
    IFEND;

  /find_command/
    BEGIN
      IF command_table = NIL THEN
        RETURN;
      IFEND;
      clp$search_command_table (state.search_name.value, command_table, entry_index, state.found);
      IF state.found THEN
        EXIT /find_command/;
      ELSEIF built_in_command_table <> NIL THEN
        RETURN;
      IFEND;
      IF state.source.utility_info^.dialog_info.commands <> NIL THEN
        command_table := state.source.utility_info^.dialog_info.commands;
        clp$search_command_table (state.search_name.value, command_table, entry_index, state.found);
        IF state.found THEN
          state.source.auxilliary_table := TRUE;
          EXIT /find_command/;
        IFEND;
      IFEND;
      IF state.source.utility_info^.auxiliary_libraries <> NIL THEN
        process_command_in_aux_library (state, status);
      IFEND;
      RETURN;
    END /find_command/;

    IF built_in_command_table = NIL THEN
      pmp$get_task_id (current_task_id, status);
      IF NOT status.normal THEN
        RETURN;
      ELSEIF NOT ((state.source.utility_info^.task_id = current_task_id) OR
            (state.source.utility_info^.command_level AND (NOT state.source.auxilliary_table))) THEN
        osp$set_status_abnormal ('CL', cle$util_cmds_fctns_unavailable, state.name.value, status);
        RETURN;
      IFEND;
      state.command_logging_completed := state.command_logging_completed OR
            (NOT state.source.utility_info^.subcommand_logging_enabled);
      state.source.utility_termination_command := command_table^ [entry_index].ordinal =
            state.source.utility_info^.termination_command_ordinal;
    IFEND;

    state.command_log_option := command_table^ [entry_index].log_option;
    state.data.ordinal := command_table^ [entry_index].ordinal;
    state.data.call_method := command_table^ [entry_index].call_method;
    IF state.search_level = clc$direct_search THEN
      state.source.ordinal := command_table^ [entry_index].ordinal;
    IFEND;

    CASE state.data.call_method OF

    = clc$linked_call =
      invoke_sub_command (state, command_table^ [entry_index].command, status);

    = clc$unlinked_call =
      IF state.data.generic_source = clc$gcs_system_built_in THEN
        REPEAT
          clp$load_system_entry_point (command_table^ [entry_index].procedure_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 (command_table^ [entry_index].procedure_name, pmc$procedure_address, loaded_address, status);
      IFEND;
      IF status.normal THEN
        #CONVERT_POINTER_TO_PROCEDURE (loaded_address.pointer_to_procedure, loaded_command);
      IFEND;
      IF (NOT status.normal) OR (loaded_command = NIL) THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
        RETURN;
      IFEND;
      invoke_sub_command (state, loaded_command, status);

    = clc$proc_call, clc$program_call =
      IF (built_in_command_table = NIL) AND (state.source.utility_info^.libraries <> NIL) THEN
        process_command_in_utility_lib (state, command_table^ [entry_index].procedure_name, status);
      ELSE
        clp$find_cmnd_or_func_in_prog (command_table^ [entry_index].procedure_name, clc$command,
              state.work_area^, state.file.local_file_name, state.ring_attributes, state.library_search_info,
              status);
        IF NOT status.normal THEN
          osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
          RETURN;
        IFEND;
        state.command_log_option := state.library_search_info.log_option;
        state.file_id := amv$nil_file_identifier;
        state.nested_commands_can_be_echoed := FALSE;
        invoke_command_in_library (state, command_table^ [entry_index].procedure_name, TRUE, status);
      IFEND;
    ELSE
      osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
    CASEND;

  PROCEND process_sub_command;
?? TITLE := 'invoke_command_in_library', EJECT ??

  PROCEDURE invoke_command_in_library
    (VAR state {input, output} : clt$command_search_state;
         processor_name: pmt$program_name;
         use_current_program: boolean;
     VAR status: ost$status);

    VAR
      condition_count: 0 .. 1,
      file_count: 0 .. pmc$max_object_file_list,
      ignore_line_layout: clt$line_layout,
      library_count: 0 .. pmc$max_library_list,
      library_program_attributes: ^llt$program_attributes,
      library_program_description: ^llt$program_description,
      module_count: 0 .. pmc$max_module_list,
      object_library_list: ^pmt$object_library_list,
      program_attributes: ^pmt$program_attributes,
      program_description: ^pmt$program_description;


    status.normal := TRUE;
    state.data.ordinal := state.library_search_info.ordinal;
    CASE state.library_search_info.module_kind OF

    = llc$command_procedure, llc$applic_command_procedure =
      invoke_scl_procedure (state, ignore_line_layout, status);

    = llc$program_description, llc$applic_program_description =
      library_program_description := state.library_search_info.command_or_function_module;
      NEXT library_program_attributes IN library_program_description;
      IF pmc$object_file_list_specified IN library_program_attributes^.contents THEN
        file_count := library_program_attributes^.number_of_object_files;
      ELSE
        file_count := 0;
      IFEND;
      IF pmc$module_list_specified IN library_program_attributes^.contents THEN
        module_count := library_program_attributes^.number_of_modules;
      ELSE
        module_count := 0;
      IFEND;
      IF pmc$library_list_specified IN library_program_attributes^.contents THEN
        library_count := library_program_attributes^.number_of_libraries;
      ELSE
        library_count := 0;
      IFEND;
      IF pmc$condition_specified IN library_program_attributes^.contents THEN
        condition_count := 1;
      ELSE
        condition_count := 0;
      IFEND;
      PUSH program_description: [[REP #SIZE (pmt$program_attributes) +
            (file_count * #SIZE (amt$local_file_name)) + (module_count *
            #SIZE (pmt$program_name)) + (library_count * #SIZE (amt$local_file_name)) +
            (condition_count * #SIZE (pmt$enable_inhibit_conditions)) OF cell]];
      invoke_program_command (state, library_program_description, program_description, status);

    = llc$load_module =
      IF use_current_program THEN
        pmp$get_program_size (file_count, module_count, library_count, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        PUSH program_description: [[REP #SIZE (pmt$program_attributes) +
              (file_count * #SIZE (amt$local_file_name)) + (module_count *
              #SIZE (pmt$program_name)) + (library_count * #SIZE (amt$local_file_name)) OF cell]];
        pmp$get_program_description (program_description^, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        RESET program_description;
        NEXT program_attributes IN program_description;
        program_attributes^.contents := program_attributes^.contents +
              $pmt$prog_description_contents [pmc$starting_proc_specified];
        program_attributes^.starting_procedure := processor_name;
      ELSE
        PUSH program_description: [[pmt$program_attributes, REP 1 OF amt$local_file_name]];
        RESET program_description;
        NEXT program_attributes IN program_description;
        program_attributes^.contents := $pmt$prog_description_contents
              [pmc$starting_proc_specified, pmc$library_list_specified];
        program_attributes^.starting_procedure := processor_name;
        program_attributes^.number_of_libraries := 1;
        NEXT object_library_list: [1 .. 1] IN program_description;
        object_library_list^ [1] := state.file.local_file_name;
      IFEND;
      invoke_program_command (state, NIL, program_description, status);

    = llc$command_description, llc$applic_command_description =
      invoke_described_command (state, status);
    CASEND;

  PROCEND invoke_command_in_library;
?? TITLE := 'convert_program_description', EJECT ??

  PROCEDURE convert_program_description
    (    state: clt$command_search_state;
         original_program_description: ^llt$program_description;
         converted_program_description: ^pmt$program_description;
     VAR status: ost$status);

    VAR
      enable_inhibit_conditions: ^pmt$enable_inhibit_conditions,
      file_count: 0 .. pmc$max_object_file_list,
      file_index: 1 .. pmc$max_object_file_list,
      ignore_evaluated_file_reference: fst$evaluated_file_reference,
      library_count: 0 .. pmc$max_library_list,
      library_enable_inhib_conditions: ^pmt$enable_inhibit_conditions,
      library_index: 1 .. pmc$max_library_list,
      library_module_list: ^pmt$module_list,
      library_object_file_list: ^llt$object_file_list,
      library_object_library_list: ^llt$object_library_list,
      library_program_attributes: ^llt$program_attributes,
      library_program_description: ^llt$program_description,
      module_count: 0 .. pmc$max_module_list,
      module_index: 1 .. pmc$max_module_list,
      module_list: ^pmt$module_list,
      object_file_list: ^pmt$object_file_list,
      object_library_list: ^pmt$object_library_list,
      program_attributes: ^pmt$program_attributes,
      program_description: ^pmt$program_description,
      program_file: clt$file;


    status.normal := TRUE;
    library_program_description := original_program_description;
    RESET library_program_description;
    NEXT library_program_attributes IN library_program_description;
    program_description := converted_program_description;
    RESET program_description;
    NEXT program_attributes IN program_description;
    file_count := 0;
    library_count := 0;

    program_attributes^.contents := library_program_attributes^.contents;
    IF pmc$starting_proc_specified IN program_attributes^.contents THEN
      program_attributes^.starting_procedure := library_program_attributes^.starting_procedure;
    IFEND;

    IF pmc$object_file_list_specified IN program_attributes^.contents THEN
      program_attributes^.number_of_object_files := library_program_attributes^.number_of_object_files;
      NEXT library_object_file_list: [1 .. program_attributes^.number_of_object_files] IN
            library_program_description;
      NEXT object_file_list: [1 .. program_attributes^.number_of_object_files] IN program_description;
      FOR file_index := 1 TO program_attributes^.number_of_object_files DO
        clp$convert_str_to_path_handle (library_object_file_list^ [file_index], FALSE,
              state.interpreter_mode = clc$help_mode, TRUE, program_file.local_file_name,
              ignore_evaluated_file_reference, status);
        IF NOT status.normal THEN
          osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
          RETURN;
        IFEND;
        object_file_list^ [file_index] := program_file.local_file_name;
      FOREND;
    IFEND;

    IF pmc$module_list_specified IN program_attributes^.contents THEN
      program_attributes^.number_of_modules := library_program_attributes^.number_of_modules;
      NEXT library_module_list: [1 .. program_attributes^.number_of_modules] IN library_program_description;
      NEXT module_list: [1 .. program_attributes^.number_of_modules] IN program_description;
      module_list^ := library_module_list^;
    IFEND;

    IF pmc$library_list_specified IN program_attributes^.contents THEN
      program_attributes^.number_of_libraries := library_program_attributes^.number_of_libraries;
      NEXT library_object_library_list: [1 .. program_attributes^.number_of_libraries] IN
            library_program_description;
      NEXT object_library_list: [1 .. program_attributes^.number_of_libraries] IN program_description;
      FOR library_index := 1 TO program_attributes^.number_of_libraries DO
        IF library_object_library_list^ [library_index] = loc$task_services_library_name THEN
          object_library_list^ [library_index] := loc$task_services_library_name;
        ELSEIF library_object_library_list^ [library_index] = 'OSF$CURRENT_LIBRARY' THEN
          object_library_list^ [library_index] := state.file.local_file_name;
        ELSE
          clp$convert_string_to_file (library_object_library_list^ [library_index], program_file, status);
          IF NOT status.normal THEN
            osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
            RETURN;
          IFEND;
          object_library_list^ [library_index] := program_file.local_file_name;
        IFEND;
      FOREND;
    IFEND;

    IF pmc$condition_specified IN program_attributes^.contents THEN
      NEXT library_enable_inhib_conditions IN library_program_description;
      NEXT enable_inhibit_conditions IN program_description;
      enable_inhibit_conditions^ := library_enable_inhib_conditions^;
    IFEND;

    IF pmc$load_map_file_specified IN program_attributes^.contents THEN
      clp$convert_string_to_file (library_program_attributes^.load_map_file, program_file, status);
      IF NOT status.normal THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
        RETURN;
      IFEND;
      program_attributes^.load_map_file := program_file.local_file_name;
    IFEND;

    IF pmc$load_map_options_specified IN program_attributes^.contents THEN
      program_attributes^.load_map_options := library_program_attributes^.load_map_options;
    IFEND;
    IF pmc$term_error_level_specified IN program_attributes^.contents THEN
      program_attributes^.termination_error_level := library_program_attributes^.termination_error_level;
    IFEND;
    IF pmc$preset_specified IN program_attributes^.contents THEN
      program_attributes^.preset := library_program_attributes^.preset;
    IFEND;
    IF pmc$max_stack_size_specified IN program_attributes^.contents THEN
      program_attributes^.maximum_stack_size := library_program_attributes^.maximum_stack_size;
    IFEND;

    IF pmc$debug_input_specified IN program_attributes^.contents THEN
      clp$convert_string_to_file (library_program_attributes^.debug_input, program_file, status);
      IF NOT status.normal THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
        RETURN;
      IFEND;
      program_attributes^.debug_input := program_file.local_file_name;
    IFEND;

    IF pmc$debug_output_specified IN program_attributes^.contents THEN
      clp$convert_string_to_file (library_program_attributes^.debug_output, program_file, status);
      IF NOT status.normal THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
        RETURN;
      IFEND;
      program_attributes^.debug_output := program_file.local_file_name;
    IFEND;

    IF pmc$abort_file_specified IN program_attributes^.contents THEN
      clp$convert_string_to_file (library_program_attributes^.abort_file, program_file, status);
      IF NOT status.normal THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
        RETURN;
      IFEND;
      program_attributes^.abort_file := program_file.local_file_name;
    IFEND;

    IF pmc$debug_mode_specified IN program_attributes^.contents THEN
      program_attributes^.debug_mode := library_program_attributes^.debug_mode;
    IFEND;

  PROCEND convert_program_description;
?? TITLE := 'invoke_scl_procedure', EJECT ??

  PROCEDURE invoke_scl_procedure
    (VAR state {input, output} : clt$command_search_state;
         line_layout: clt$line_layout;
     VAR status: ost$status);

    VAR
      converter: record
        case 0 .. 1 of
        = 0 =
          procedure_pointer: ^procedure
                 (VAR state {input, output} : clt$command_search_state;
                      line_layout: clt$line_layout;
                  VAR status: ost$status),
        = 1 =
          code_base_pointer: ^ost$external_code_base_pointer,
        casend,
      recend,
      end_proc_block: ^clt$block,
      header: ^clt$scl_procedure_header,
      parameters_work_area: ^^clt$work_area,
      pop_status: ost$status,
      proc_data: ^clt$scl_procedure,
      proc_status: ost$status,
      version: clt$declaration_version;

?? NEWTITLE := 'command_procedure_cond_handler', EJECT ??

{
{ PURPOSE:
{   This condition handler duplicates most of the command_condition_handler
{   within clp$process_commands.  It is allows any condition that arise to be
{   processed in the ring in which the command processor runs.
{

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

      VAR
        exit_control_block: ^clt$block,
        ignore_status: ost$status,
        run_time_status: ^ost$status;


      CASE condition.selector OF

      = pmc$block_exit_processing =

{ --- Handle block exit.

        IF state.command_block <> NIL THEN
          clp$pop_terminated_blocks (state.command_block, status);
          handle_exit_from_procedure;
        IFEND;
        RETURN;

      = mmc$segment_access_condition =

{ --- Handle segment access conditions.

        osp$set_status_from_condition ('CL', condition, save_area, status, state.ignore_status);
        IF (status.condition = cle$work_area_overflow) AND (status.text.size = 0) AND state.found THEN
          osp$append_status_parameter (osc$status_parameter_delimiter, state.name.value, status);
        IFEND;
        EXIT invoke_scl_procedure;

      = pmc$system_conditions =

{ --- Handle system (hardware detected) conditions.

        IF pmc$detected_uncorrected_err IN condition.system_conditions THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, state.ignore_status);
        IFEND;
        osp$set_status_from_condition ('CL', condition, save_area, status, state.ignore_status);
        EXIT invoke_scl_procedure;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN

{ --- Handle CYBIL run time error.

          run_time_status := condition_information;
          status := run_time_status^;
          EXIT invoke_scl_procedure;

        ELSEIF (condition.user_condition_name = clc$exiting_condition) AND (state.command_block <> NIL) AND
              state.command_block^.being_exited 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.

          exit_control_block := condition_information;
          IF #OFFSET (exit_control_block) <> #OFFSET (state.command_block) THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          IFEND;
          EXIT invoke_scl_procedure;

        ELSE

{ --- "Continue" any other user defined condition.

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

      ELSE

{ --- "Continue" any other condition.

        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
        RETURN;
      CASEND;

    PROCEND command_procedure_cond_handler;
?? TITLE := 'handle_exit_from_procedure', EJECT ??

    PROCEDURE [INLINE] handle_exit_from_procedure;

      VAR
        connected_files: ^clt$connected_files,
        ignore_cond_processed_state: clt$condition_processed_state;


      clp$process_exit_condition (state.command_block, status);
      IF status.normal AND (state.command_block^.command_proc_status <> NIL) AND
            (NOT state.command_block^.command_proc_status^.normal) THEN
        status := state.command_block^.command_proc_status^;
      IFEND;
      IF status.normal THEN
        proc_status.normal := TRUE;
      ELSE
        proc_status := status;
      IFEND;

      IF state.command_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_COMMAND_PROC_END', ^state.name.value,
                ^state.file.local_file_name, ^proc_status, state.ignore_status);
        IFEND;
      IFEND;

    PROCEND handle_exit_from_procedure;
?? TITLE := 'my_parameter_list', EJECT ??

    FUNCTION my_parameter_list: ^cell;

      VAR
        psa: ^ost$stack_frame_save_area;


      psa := #PREVIOUS_SAVE_AREA ();
      my_parameter_list := psa^.a4;

    FUNCEND my_parameter_list;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    IF (state.source.kind <> clc$catalog_commands) AND (state.ring_attributes.r2 < #RING (^converter)) THEN

{ This routine must call itself at the target ring in order to process the procedure at that ring.

      converter.procedure_pointer := ^invoke_scl_procedure;
      pmp$inward_call (converter.code_base_pointer, state.ring_attributes.r2, my_parameter_list (),
            #PREVIOUS_SAVE_AREA ());

{ The above call to PMP$INWARD_CALL should result in control being returned
{ directly to this procedure's caller.  The following RETURN statement is
{ here just for "safety's sake".

      RETURN;
    IFEND;

    state.data.call_method := clc$proc_call;
    emit_processed_command_stat (state);
    log_and_or_echo_command (state);

    proc_data := state.library_search_info.command_or_function_module;
    IF proc_data = NIL THEN
      header := NIL;
    ELSE
      RESET proc_data;
      NEXT header IN proc_data;
      IF (header = NIL) OR (header^.identifying_first_byte <> UPPERVALUE (header^.identifying_first_byte))
            THEN
        version := 0;
        header := NIL;
      ELSE
        version := header^.version;
        proc_data := #PTR (header^.procedure_body, proc_data^);
      IFEND;
      RESET proc_data;
    IFEND;

    state.nested_commands_can_be_echoed := state.nested_commands_can_be_echoed AND
          (state.command_log_option = clc$automatically_log) AND (state.interpreter_mode <> clc$help_mode);

    clp$push_command_proc_block (state.caller_ring, state.name.value, state.source,
          state.command_logging_completed, state.command_echoing_completed, state.prompting_requested,
          state.nested_commands_can_be_echoed, state.file.local_file_name, state.file_id, line_layout,
          proc_data, version, state.device_class, state.command_block);

    osp$establish_condition_handler (^command_procedure_cond_handler, TRUE);

    IF state.command_block^.input_can_be_echoed AND state.command_echoing_activated THEN
      clp$echo_trace_information ('CLC$ECHO_COMMAND_PROC_BEGIN', ^state.name.value,
            ^state.file.local_file_name, NIL, state.ignore_status);
    IFEND;

    initialize_application_info (state, status);

    IF status.normal THEN
      clp$get_work_area (#RING (^parameters_work_area), parameters_work_area, status);
      IF status.normal THEN
        clp$process_proc_parameters (clc$command, state.library_search_info.command_or_function_module,
              header, state.nested_commands_can_be_echoed, state.parse, parameters_work_area^, status);
      IFEND;
    IFEND;

    IF status.normal THEN
      clp$process_command_file (state.command_block, NIL, status);
      IF status.normal AND (state.command_block^.command_proc_status <> NIL) AND
            (NOT state.command_block^.command_proc_status^.normal) THEN
        status := state.command_block^.command_proc_status^;
      IFEND;
    IFEND;

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

    verify_block_stack_integrity (state.command_block, status);

    state.command_logging_completed := state.command_logging_completed OR
          state.command_block^.command_proc_logging_completed;
    state.command_echoing_completed := state.command_echoing_completed OR
          state.command_block^.command_proc_echoing_completed;

    handle_exit_from_procedure;

    osp$disestablish_cond_handler;

    IF state.command_block^.parameters.command_status_specified THEN
      process_command_status ('STATUS', status);
    IFEND;

    clp$pop_input_stack (end_proc_block, pop_status);
    IF status.normal AND (NOT pop_status.normal) THEN
      status := pop_status;
    IFEND;

    IF status.normal THEN
      set_prev_cmnd_name_and_stat (state, proc_status);
    ELSE
      set_prev_cmnd_name_and_stat (state, status);
    IFEND;

  PROCEND invoke_scl_procedure;
?? TITLE := 'invoke_program_command', EJECT ??

  PROCEDURE invoke_program_command
    (VAR state {input, output} : clt$command_search_state;
         library_program_description: ^llt$program_description;
         program_description: ^pmt$program_description;
     VAR status: ost$status);

    VAR
      parameter_list: clt$i_parameter_list_contents,
      program_description_pointer: ^pmt$program_description,
      program_attributes: ^pmt$program_attributes,
      target_ring: ost$valid_ring,
      task_id: pmt$task_id,
      task_status: pmt$task_status;


    status.normal := TRUE;
    state.data.call_method := clc$program_call;
    emit_processed_command_stat (state);
    log_and_or_echo_command (state);

    clp$push_command_block (state.caller_ring, state.name.value, state.source,
          state.command_logging_completed, state.command_echoing_completed, state.prompting_requested,
          clc$program_command, state.parse, state.command_block);

    initialize_application_info (state, status);

    IF status.normal AND (library_program_description <> NIL) THEN
      convert_program_description (state, library_program_description, program_description, status);
    IFEND;

    IF status.normal THEN
      IF state.interpreter_mode = clc$help_mode THEN
        program_description_pointer := program_description;
        RESET program_description_pointer;
        NEXT program_attributes IN program_description_pointer;
        program_attributes^.contents := program_attributes^.contents +
              $pmt$prog_description_contents [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^.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 := UPPERVALUE (pmt$termination_error_level);
        program_attributes^.abort_file := clv$standard_files [clc$sf_null_file].path_handle_name;
        program_attributes^.debug_mode := FALSE;
      IFEND;

      parameter_list.identifying_size_field := UPPERVALUE (parameter_list.identifying_size_field);

      IF state.source.kind = clc$catalog_commands THEN
        target_ring := state.caller_ring;
      ELSEIF state.caller_ring < state.ring_attributes.r1 THEN
        target_ring := state.ring_attributes.r1;
      ELSEIF state.caller_ring > state.ring_attributes.r2 THEN
        target_ring := state.ring_attributes.r2;
      ELSE
        target_ring := state.caller_ring;
      IFEND;

      IF state.command_from_execute_command THEN

{ If an outward call to the task is made, we will never return from this call.

        pmp$execute_within_task (program_description^, #SEQ (parameter_list) ^, status);
      ELSEIF target_ring <> state.caller_ring THEN
        clp$execute_named_task (osc$null_name, target_ring, program_description^, #SEQ (parameter_list) ^,
              osc$null_name, task_id, status);
      ELSE
        pmp$execute (program_description^, #SEQ (parameter_list) ^, osc$wait, task_id, task_status, status);
        IF status.normal AND (NOT task_status.status.normal) THEN
          status := task_status.status;
        IFEND;
      IFEND;
    IFEND;

    verify_block_stack_integrity (state.command_block, status);

    state.command_logging_completed := state.command_logging_completed OR
          state.command_block^.command_logging_completed;
    state.command_echoing_completed := state.command_echoing_completed OR
          state.command_block^.command_echoing_completed;

    set_prev_cmnd_name_and_stat (state, status);

    IF state.command_block^.parameters.command_status_variable <> NIL THEN
      process_command_status (state.command_block^.parameters.command_status_variable^, status);
    IFEND;

    clp$pop_block_stack (state.command_block);

  PROCEND invoke_program_command;
?? TITLE := 'invoke_sub_command', EJECT ??

  PROCEDURE invoke_sub_command
    (VAR state {input, output} : clt$command_search_state;
         command: clt$command;
     VAR status: ost$status);

?? NEWTITLE := 'invoke_condition_handler', EJECT ??

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


      CASE condition.selector OF
      = pmc$system_conditions =
        IF (($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
          osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
          EXIT invoke_sub_command;
        IFEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = clc$command_cleanup_completed THEN

{ This deals with the INCLUDE_COMMAND command's need to do its own cleanup.

          command_cleanup_completed := TRUE;
          RETURN;
        IFEND;
      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND invoke_condition_handler;
?? OLDTITLE, EJECT ??

    VAR
      callers_save_area: ^ost$stack_frame_save_area,
      command_cleanup_completed: boolean,
      parameter_list: clt$i_parameter_list_contents;


    status.normal := TRUE;

    IF state.command_block = NIL THEN
      emit_processed_command_stat (state);
      log_and_or_echo_command (state);

      clp$push_command_block (state.caller_ring, state.name.value, state.source,
            state.command_logging_completed, state.command_echoing_completed, state.prompting_requested,
            clc$regular_command, state.parse, state.command_block);
    IFEND;

    initialize_application_info (state, status);

    callers_save_area := #PREVIOUS_SAVE_AREA ();
    command_cleanup_completed := FALSE;
    parameter_list.identifying_size_field := UPPERVALUE (parameter_list.identifying_size_field);

    osp$establish_condition_handler (^invoke_condition_handler, FALSE);
    command^ (#SEQ (parameter_list) ^, status);
    osp$disestablish_cond_handler;

    IF (NOT status.normal) AND (status.condition = cle$unknown_command) AND (status.text.size = 0) THEN
      osp$append_status_parameter (osc$status_parameter_delimiter, state.name.value, status);
    IFEND;

    state.command_logging_completed := state.command_logging_completed OR
          state.command_block^.command_logging_completed;
    state.command_echoing_completed := state.command_echoing_completed OR
          state.command_block^.command_echoing_completed;

    IF command_cleanup_completed AND (state.interpreter_mode <> clc$help_mode) THEN
      RETURN;
    IFEND;

    verify_block_stack_integrity (state.command_block, status);

    IF state.interpreter_mode = clc$interpret_mode THEN
      set_prev_cmnd_name_and_stat (state, status);

      IF state.command_block^.parameters.command_status_variable <> NIL THEN
        process_command_status (state.command_block^.parameters.command_status_variable^, status);
      IFEND;
    IFEND;

    clp$pop_block_stack (state.command_block);

  PROCEND invoke_sub_command;
?? TITLE := 'invoke_described_command', EJECT ??

  PROCEDURE invoke_described_command
    (VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);

    VAR
      command_description_contents: ^llt$command_desc_contents,
      converter: record
        case 0 .. 1 of
        = 0 =
          procedure_pointer: ^procedure
                 (VAR state {input, output} : clt$command_search_state;
                  VAR status: ost$status),
        = 1 =
          code_base_pointer: ^ost$external_code_base_pointer,
        casend,
      recend,
      library_file: clt$file,
      library_path: ^fst$file_reference,
      loaded_address: pmt$loaded_address,
      loaded_command: clt$command,
      search_$system_option: clt$search_$system_option;

?? NEWTITLE := 'described_command_cond_handler', EJECT ??

{
{ PURPOSE:
{   This condition handler duplicates most of the command_condition_handler
{   within clp$process_commands.  It is allows any condition that arise to be
{   processed in the ring in which the command processor runs.
{

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

      VAR
        exit_control_block: ^clt$block,
        ignore_status: ost$status,
        run_time_status: ^ost$status;


      CASE condition.selector OF

      = pmc$block_exit_processing =

{ --- Handle block exit.

        RETURN;

      = mmc$segment_access_condition =

{ --- Handle segment access conditions.

        osp$set_status_from_condition ('CL', condition, save_area, status, state.ignore_status);
        IF (status.condition = cle$work_area_overflow) AND (status.text.size = 0) AND state.found THEN
          osp$append_status_parameter (osc$status_parameter_delimiter, state.name.value, status);
        IFEND;
        EXIT invoke_described_command;

      = pmc$system_conditions =

{ --- Handle system (hardware detected) conditions.

        IF pmc$detected_uncorrected_err IN condition.system_conditions THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, state.ignore_status);
        IFEND;
        osp$set_status_from_condition ('CL', condition, save_area, status, state.ignore_status);
        EXIT invoke_described_command;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN

{ --- Handle CYBIL run time error.

          run_time_status := condition_information;
          status := run_time_status^;
          EXIT invoke_described_command;

        ELSEIF (condition.user_condition_name = clc$exiting_condition) AND (state.command_block <> NIL) AND
              state.command_block^.being_exited 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.

          exit_control_block := condition_information;
          IF #OFFSET (exit_control_block) <> #OFFSET (state.command_block) THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          IFEND;
          EXIT invoke_described_command;

        ELSE

{ --- "Continue" any other user defined condition.

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

      ELSE

{ --- "Continue" any other condition.

        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
        RETURN;
      CASEND;

    PROCEND described_command_cond_handler;
?? TITLE := 'my_parameter_list', EJECT ??

    FUNCTION my_parameter_list: ^cell;

      VAR
        psa: ^ost$stack_frame_save_area;


      psa := #PREVIOUS_SAVE_AREA ();
      my_parameter_list := psa^.a4;

    FUNCEND my_parameter_list;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    IF state.ring_attributes.r2 < #RING (^converter) THEN

{ This routine must call itself at the target ring in order to process the command at that ring.

      converter.procedure_pointer := ^invoke_described_command;
      pmp$inward_call (converter.code_base_pointer, state.ring_attributes.r2, my_parameter_list (),
            #PREVIOUS_SAVE_AREA ());

{ The above call to PMP$INWARD_CALL should result in control being returned
{ directly to this procedure's caller.  The following RETURN statement is
{ here just for "safety's sake".

      RETURN;
    IFEND;

    state.data.call_method := clc$unlinked_call;

    NEXT command_description_contents IN state.library_search_info.command_or_function_module;
    IF command_description_contents = NIL THEN
      osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
      RETURN;
    IFEND;

    IF command_description_contents^.system_command THEN
      IF state.source.kind = clc$system_commands THEN
        search_$system_option := clc$skip_system_library;
      ELSE
        search_$system_option := clc$search_system_library;
      IFEND;
      state.search_level := clc$indirect_search;
      state.search_name.size := clp$trimmed_string_size (command_description_contents^.system_command_name);
      state.search_name.value := command_description_contents^.system_command_name;
      state.found := FALSE;
      process_system_command (search_$system_option, state, status);
      IF status.normal AND (NOT state.found) THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
      IFEND;
      state.found := TRUE;
      RETURN;
    IFEND;

    emit_processed_command_stat (state);
    log_and_or_echo_command (state);

    clp$push_command_block (state.caller_ring, state.name.value, state.source,
          state.command_logging_completed, state.command_echoing_completed, state.prompting_requested,
          clc$regular_command, state.parse, state.command_block);

    osp$establish_condition_handler (^described_command_cond_handler, FALSE);

    IF command_description_contents^.library_path_size > 0 THEN
      NEXT library_path: [command_description_contents^.library_path_size] IN
            state.library_search_info.command_or_function_module;
      IF library_path = NIL THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
        clp$pop_block_stack(state.command_block);
        RETURN;
      ELSEIF library_path^ = 'OSF$CURRENT_LIBRARY' THEN
        library_file.local_file_name := state.file.local_file_name;
      ELSE
        clp$convert_string_to_file (library_path^, library_file, status);
        IF NOT status.normal THEN
          osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
          clp$pop_block_stack(state.command_block);
          RETURN;
        IFEND;
      IFEND;
      IF state.file.local_file_name = osc$null_name THEN
        clp$load_system_entry_point (command_description_contents^.starting_procedure, pmc$procedure_address,
              loaded_address, status);
      ELSE
        clp$load_from_library (command_description_contents^.starting_procedure, pmc$procedure_address,
              library_file.local_file_name, loaded_address, status);
      IFEND;
    ELSE
      pmp$load (command_description_contents^.starting_procedure, pmc$procedure_address, loaded_address,
            status);
    IFEND;

    IF status.normal THEN
      #CONVERT_POINTER_TO_PROCEDURE (loaded_address.pointer_to_procedure, loaded_command);
    IFEND;
    IF (NOT status.normal) OR (loaded_command = NIL) THEN
      osp$set_status_abnormal ('CL', cle$unable_to_call_command, state.name.value, status);
      clp$pop_block_stack(state.command_block);
      RETURN;
    IFEND;

    invoke_sub_command (state, loaded_command, status);

  PROCEND invoke_described_command;
?? TITLE := 'process_system_command', EJECT ??

  PROCEDURE [INLINE] process_system_command
    (    search_option: clt$search_$system_option;
     VAR state {input, output} : clt$command_search_state;
     VAR status: ost$status);


    status.normal := TRUE;

    IF jmp$system_job () THEN
      state.data.generic_source := clc$gcs_system_built_in;
      IF state.search_level = clc$direct_search THEN
        state.source.system_command_table := clv$operator_commands;
      IFEND;
      process_sub_command (state, clv$operator_commands, status);
    IFEND;

    IF status.normal AND (NOT state.found) THEN
      IF search_option = clc$search_system_library THEN
        IF (state.command_list^.system_command_library_lfn <> osc$null_name) AND
              state.command_list^.system_library_contains.commands THEN
          state.file.local_file_name := osc$null_name;
          state.path_description_obtained := FALSE;
          IF state.search_level = clc$direct_search THEN
            state.source.system_command_table := NIL;
          IFEND;
          process_command_in_library (FALSE, state, status);
        IFEND;
      IFEND;

      IF status.normal AND (NOT state.found) THEN
{Add this back in when we have a $SYSTEM entry
        state.data.generic_source := clc$gcs_system_built_in;
        IF state.search_level = clc$direct_search THEN
          state.source.system_command_table := clv$system_commands;
        IFEND;
        process_sub_command (state, clv$system_commands, status);
      IFEND;
    IFEND;

  PROCEND process_system_command;
?? TITLE := 'process_command_status', EJECT ??

  PROCEDURE [INLINE] process_command_status
    (    status_variable: clt$variable_ref_expression;
     VAR status {input, output} : ost$status);

    VAR
      status_value: ^clt$data_value;


    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);

  PROCEND process_command_status;
?? TITLE := 'verify_block_stack_integrity', EJECT ??

  PROCEDURE [INLINE] verify_block_stack_integrity
    (    command_block: ^clt$block;
     VAR status {input,output} : ost$status);

    VAR
      current_block: ^clt$block;


    clp$find_current_block (current_block);
    WHILE current_block <> command_block DO
      IF current_block^.kind = clc$task_block THEN
        osp$system_error ('SCL Block Stack Corrupted', ^status);
      IFEND;
      current_block := current_block^.previous_block;
    WHILEND;

    clp$pop_terminated_blocks (command_block, status);

  PROCEND verify_block_stack_integrity;
?? TITLE := 'clp$asynchronous_command', EJECT ??

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

    CONST
      not_from_job_command_file = FALSE,
      command_from_execute_command = TRUE,
      dont_log_the_command = FALSE;

    VAR
      block: ^clt$block,
      program_parameters: ^pmt$program_parameters,
      ignore_cause_condition: clt$when_condition,
      command_parameters: ^clt$async_command_parameters;


    status.normal := TRUE;

    program_parameters := ^parameter_list;
    RESET program_parameters;
    NEXT command_parameters IN program_parameters;
    IF (command_parameters = NIL) OR (command_parameters^.text_size = 0) THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$asynchronous_command', status);
      RETURN;
    IFEND;

    NEXT command_parameters^.parse.text: [command_parameters^.text_size] IN program_parameters;
    IF command_parameters^.parse.text = NIL THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$asynchronous_command', status);
      RETURN;
    IFEND;

    NEXT command_parameters^.parse.units_array: [1 .. command_parameters^.units_array_size] IN
          program_parameters;
    IF command_parameters^.parse.units_array = NIL THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$asynchronous_command', status);
      RETURN;
    IFEND;

    IF command_parameters^.init_from_desktop_environment THEN
      osp$set_desktop_interaction (status);
      IF NOT status.normal THEN
        osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$asynchronous_command', status);
        RETURN;
      IFEND;
    IFEND;

    clp$find_current_block (block);
    clp$process_command (block, clc$interpret_mode, not_from_job_command_file, command_from_execute_command,
          dont_log_the_command, command_parameters^.command_can_be_echoed, command_parameters^.parse,
          ignore_cause_condition, status);

  PROCEND clp$asynchronous_command;

MODEND clm$process_commands;
