?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Input Procedures' ??
MODULE clm$input_procedures;

{
{ PURPOSE:
{   This module contains the procedures that read data from the current command input file.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clc$compiling_for_test_harness
*copyc clc$lexical_units_size_pad
*copyc clc$standard_file_names
*copyc cle$ecc_command_processing
*copyc cle$ecc_messages_and_prompts
*copyc cle$ecc_miscellaneous
*copyc cle$ecc_utilities
*copyc clh$utility_line_preprocessor
*IF NOT $true(osv$unix)
*ELSE
*copyc cyt$mips_signal_handler
*copyc osv$signal
*copyc osv$signal_status
*copyc clp$determine_line_layout
*copyc fst$path_size
*copyc amc_standard_files
*copyc clv$standard_files
*IFEND
*copyc clt$command_line
*IF NOT $true(osv$unix)
*copyc clt$scl_procedure
*copyc clt$scl_procedure_header
*IFEND
*copyc clt$utility_line_preprocessor
*IF NOT $true(osv$unix)
*copyc cyd$run_time_error_condition
*copyc fmt$path_handle
*copyc fst$evaluated_file_reference
*IFEND
*copyc fst$file_reference
*IF NOT $true(osv$unix)
*copyc ife$error_codes
*IFEND
*copyc ift$format_effectors
*IF NOT $true(osv$unix)
*copyc ost$caller_identifier
*IFEND
*copyc ost$status
?? POP ??
*copyc amp$get_next
*copyc amp$get_partial
*IF NOT $true(osv$unix)
*copyc amp$seek_direct
*ELSE
*copyc amp$put_partial
*copyc amc_standard_files
*IFEND
*copyc amv$nil_file_identifier
*copyc clp$access_command_file
*copyc clp$append_continuation_line
*copyc clp$close_command_file
*IF NOT $true(osv$unix)
*copyc clp$convert_file_ref_to_string
*IFEND
*copyc clp$convert_str_to_path_handle
*IF NOT $true(osv$unix)
*copyc clp$echo_trace_information
*copyc clp$find_caller_input_block
*IFEND
*copyc clp$find_command_input_block
*IF NOT $true(osv$unix)
*copyc clp$find_connected_files
*IFEND
*copyc clp$find_current_block
*copyc clp$find_external_input_block
*copyc clp$find_input_block
*copyc clp$get_command_origin
*copyc clp$identify_lexical_units
*IF NOT $true(osv$unix)
*copyc clp$init_input_parse_state
*IFEND
*copyc clp$layout_data_line
*copyc clp$pop_input_stack
*copyc clp$pop_terminated_blocks
*copyc clp$push_input_$command_block
*copyc clp$push_input_file_block
*copyc clp$set_current_prompt_string
*copyc clp$set_input_line
*copyc clp$trimmed_string_size
*copyc clv$nil_block_handle
*IF NOT $true(osv$unix)
*copyc clv$standard_files
*copyc i#build_adaptable_seq_pointer
*IFEND
*copyc i#current_sequence_position
*IF NOT $true(osv$unix)
*copyc ifp$store_term_conn_attributes
*copyc jmp$system_job
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$establish_condition_handler
*IFEND
*copyc osp$generate_message
*copyc osp$generate_output_message
*copyc osp$set_status_abnormal
*IF NOT $true(osv$unix)
*copyc osp$set_status_from_condition
*copyc osp$enforce_exception_policies
*copyc osp$file_access_condition
*copyc osv$initial_exception_context
*IFEND
*copyc osv$lower_to_upper
*IF NOT $true(osv$unix)
*copyc pmp$continue_to_cause
*copyc pmp$get_job_mode
*copyc pmp$load
*copyc pmp$task_state
*IFEND

  CONST
    clc$continued_same_line_prompt = ifc$pre_print_space_1 CAT '..? ',
    clc$cont_same_line_prompt_size = 5,
    clc$same_line_prompt = ifc$pre_print_no_positioning CAT ' ',
    clc$same_line_prompt_size = 2;

*IF $true(osv$unix)
*copyc osp$append_status_file
*IFEND
?? TITLE := 'clp$push_input', EJECT ??
*copyc clh$push_input

  PROCEDURE [XDCL, #GATE] clp$push_input
    (    file: fst$file_reference;
         utility_name: ost$name;
         prompt_string: clt$prompt_string;
         enable_echoing: boolean;
         read_only: boolean;
     VAR input_block_handle: clt$block_handle;
     VAR file_id: amt$file_identifier;
     VAR opened_executable_file: boolean;
     VAR status: ost$status);

    VAR
*IF NOT $true(osv$unix)
      caller_id: ost$caller_identifier,
*IFEND
      caller_input_block: ^clt$block,
      caller_in_current_task: boolean,
      can_be_echoed: boolean,
*IF NOT $true(osv$unix)
      connected_files: ^clt$connected_files,
*IFEND
      device_class: rmt$device_class,
      evaluated_file_reference: fst$evaluated_file_reference,
      file_has_fap: boolean,
      file_type: clt$command_file_kind,
      file_path: ^fst$path,
      file_path_size: fst$path_size,
*IF $true(osv$unix)
      handler_established: boolean,
*IFEND
      ignore_byte_address: amt$file_byte_address,
*IF NOT $true(osv$unix)
      ignore_data: cell,
      ignore_file_contents: clt$file_contents,
*IFEND
      ignore_file_position: amt$file_position,
*IF NOT $true(osv$unix)
      ignore_ring_attributes: amt$ring_attributes,
*IFEND
      ignore_transfer_count: amt$transfer_count,
      input_block: ^clt$block,
      input_is_via_$command: boolean,
      line_layout: clt$line_layout,
*IF NOT $true(osv$unix)
      open_path_handle_name: fst$path_handle_name,
*ELSE
      open_path_handle_name: fst$path,
*IFEND
      open_the_file: boolean,
*IF NOT $true(osv$unix)
      path_handle_name: fst$path_handle_name,
*ELSE
      path_handle_name: fst$path,
*IFEND
      segment: ^SEQ ( * ),
*IF $true(osv$unix)
      standard_file: clt$standard_files,
*IFEND
      translated_utility_name: ost$name,
      use_path_handle_name_on_open: boolean;


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

    PROCEDURE abort_handler
*IF $true(osv$unix)
      (    signal_no: integer;
           code: integer;
           p_sigcontext: ^cyt$mips_sigcontext);

      VAR
        ignore_status: ost$status;

      clp$pop_input (read_only, input_block_handle, file_id, opened_executable_file, NIL, ignore_status);
*ELSE
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      clp$pop_input (read_only, input_block_handle, file_id, opened_executable_file, NIL, handler_status);
      handler_status.normal := TRUE;
*IFEND

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

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

*IF NOT $true(osv$unix)
    #CALLER_ID (caller_id);
*IFEND
    IF read_only THEN
      file_type := clc$get_file;
    ELSE
      file_type := clc$include_file;
    IFEND;
    can_be_echoed := TRUE;
    open_the_file := TRUE;
    file_has_fap := FALSE;

    clp$convert_str_to_path_handle (file, {delete_allowed} TRUE, {resolve_path} TRUE, {open_position} TRUE,
          path_handle_name, evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    #TRANSLATE (osv$lower_to_upper, utility_name, translated_utility_name);

*IF NOT $true(osv$unix)
    IF evaluated_file_reference.path_resolution <> fsc$command_file_path THEN
*ELSE
    IF NOT evaluated_file_reference.command_file_path.found THEN
*IFEND
      input_is_via_$command := FALSE;
*IF NOT $true(osv$unix)
      use_path_handle_name_on_open :=
            (path_handle_name = clv$standard_files [clc$sf_command_file].path_handle_name);
*ELSE
      use_path_handle_name_on_open := FALSE;
*IFEND
    ELSE
      use_path_handle_name_on_open := TRUE;
      input_is_via_$command := TRUE;
*IF NOT $true(osv$unix)
      clp$find_command_input_block (evaluated_file_reference.block_handle, caller_input_block,
*ELSE
      clp$find_command_input_block (evaluated_file_reference.command_file_path.block_handle,
            caller_input_block,
*IFEND
            caller_in_current_task);

      IF caller_input_block = NIL THEN
        osp$set_status_abnormal ('CL', cle$command_file_not_accessible, '', status);
        RETURN;
      ELSEIF (caller_input_block^.kind = clc$task_block) THEN
        path_handle_name := caller_input_block^.command_file;
        input_is_via_$command := FALSE;
      ELSE
*IF NOT $true(osv$unix)
        can_be_echoed := caller_input_block^.input_can_be_echoed;
*IFEND
        IF caller_in_current_task OR (caller_input_block^.input.kind <> clc$file_input) THEN
          open_the_file := FALSE;
        ELSE
          path_handle_name := caller_input_block^.input.local_file_name;
          IF caller_input_block^.input.data = NIL THEN
            IF read_only THEN
              file_type := clc$get_record_caller_file;
            ELSE
              file_type := clc$incf_record_caller_file;
            IFEND;
          ELSE
            IF read_only THEN
              file_type := clc$get_segment_caller_file;
            ELSE
              file_type := clc$incf_segment_caller_file;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

*IF NOT $true(osv$unix)
    IF path_handle_name = clv$standard_files [clc$sf_null_file].path_handle_name THEN
      open_the_file := FALSE;
      device_class := rmc$null_device;
    IFEND;
*ELSE
    /determine_if_standard_file/
    FOR standard_file := clc$sf_null_file TO clc$sf_command_file DO
      IF path_handle_name = clv$standard_files [standard_file].unix_file_name THEN
        open_the_file := FALSE;
        file_id := clv$standard_files [standard_file].file_id;
        IF standard_file = clc$sf_null_file THEN
          device_class := rmc$null_device;
        ELSE
          device_class := rmc$terminal_device;
        IFEND;
        clp$determine_line_layout (file, line_layout, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        EXIT /determine_if_standard_file/;
      IFEND;
    FOREND /determine_if_standard_file/;
*IFEND


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

  /push_input/
    BEGIN
      IF open_the_file THEN
*IF NOT $true(osv$unix)
        IF use_path_handle_name_on_open THEN
          clp$access_command_file (file_type, caller_id.ring, path_handle_name, file_id, segment,
                opened_executable_file, can_be_echoed, line_layout, ignore_file_contents,
                ignore_ring_attributes, file_has_fap, device_class, open_path_handle_name, status);
*ELSE
          clp$access_command_file (file_type, path_handle_name, file_id, segment,
                opened_executable_file, can_be_echoed, line_layout,
                device_class, open_path_handle_name, status);
*IFEND
*IF NOT $true(osv$unix)
        ELSE
          PUSH file_path;
          clp$convert_file_ref_to_string (evaluated_file_reference, {include_open_position} TRUE, file_path^,
                file_path_size, status);
          IF NOT status.normal THEN
            EXIT /push_input/;
          IFEND;
          clp$access_command_file (file_type, caller_id.ring, file_path^ (1, file_path_size), file_id,
                segment, opened_executable_file, can_be_echoed, line_layout, ignore_file_contents,
                ignore_ring_attributes, file_has_fap, device_class, open_path_handle_name, status);
        IFEND;
*IFEND
        IF NOT status.normal THEN
          EXIT /push_input/;
        IFEND;

*IF NOT $true(osv$unix)
        path_handle_name := open_path_handle_name;
        CASE file_type OF
        = clc$incf_segment_caller_file, clc$get_segment_caller_file =
          i#build_adaptable_seq_pointer (#RING (segment), #SEGMENT (segment),
                #OFFSET (caller_input_block^.input.data), #SIZE (caller_input_block^.input.data^),
                i#current_sequence_position (caller_input_block^.input.data), segment);
        = clc$incf_record_caller_file, clc$get_record_caller_file =
          IF caller_input_block^.input.file_rereadable THEN
            amp$seek_direct (file_id, caller_input_block^.input.line_address, status);
            IF NOT status.normal THEN
              EXIT /push_input/;
            IFEND;
            IF caller_input_block^.input.line_address_is_for_previous THEN
              amp$get_next (file_id, ^ignore_data, 1, ignore_transfer_count, ignore_byte_address,
                    ignore_file_position, status);
              IF NOT status.normal THEN
                EXIT /push_input/;
              IFEND;
            IFEND;
          IFEND;
        ELSE
          ;
        CASEND;
*IFEND
      IFEND;

*IF NOT $true(osv$unix)
      IF NOT read_only THEN
        clp$find_connected_files (connected_files);
      IFEND;
*IFEND
      IF input_is_via_$command THEN
        clp$push_input_$command_block (#OFFSET (caller_input_block), translated_utility_name, prompt_string,
              file_id, segment, (NOT read_only) AND enable_echoing AND can_be_echoed, caller_in_current_task,
              input_block);
*IF NOT $true(osv$unix)
        IF input_block^.input_can_be_echoed AND (connected_files^.echo_count > 0) THEN
          clp$echo_trace_information ('CLC$ECHO_INCLUDE_$COMMAND_BEGIN', ^translated_utility_name, NIL, NIL,
                status);
          status.normal := TRUE;
        IFEND;
*IFEND
      ELSE
        clp$push_input_file_block (path_handle_name, file_id, translated_utility_name, prompt_string,
              (NOT read_only) AND enable_echoing AND can_be_echoed, line_layout, device_class, file_has_fap,
              TRUE, input_block);
*IF NOT $true(osv$unix)
        IF input_block^.input_can_be_echoed AND (connected_files^.echo_count > 0) THEN
          clp$echo_trace_information ('CLC$ECHO_INCLUDE_FILE_BEGIN', ^translated_utility_name,
                ^path_handle_name, NIL, status);
          status.normal := TRUE;
        IFEND;
*IFEND
      IFEND;
      input_block_handle.segment_offset := #OFFSET (input_block);
      input_block_handle.assignment_counter := input_block^.assignment_counter;
    END /push_input/;

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

  PROCEND clp$push_input;
?? TITLE := 'clp$pop_input', EJECT ??
*copyc clh$pop_input

  PROCEDURE [XDCL, #GATE] clp$pop_input
    (    read_only: boolean;
         input_block_handle: clt$block_handle,
         file_id: amt$file_identifier;
         opened_executable_file: boolean;
         termination_status: ^ost$status;
     VAR status: ost$status);

    VAR
*IF NOT $true(osv$unix)
      connected_files: ^clt$connected_files,
*IFEND
      ignore_block_in_current_task: boolean,
      ignore_block_is_synchronous: boolean,
      input_block: ^clt$block,
      local_status: ost$status;


    status.normal := TRUE;

    IF input_block_handle <> clv$nil_block_handle THEN
      clp$find_block_via_handle (input_block_handle, input_block, ignore_block_in_current_task,
            ignore_block_is_synchronous);
      IF input_block <> NIL THEN
        clp$pop_terminated_blocks (input_block, status);
        IF status.normal THEN
          IF NOT read_only THEN
*IF NOT $true(osv$unix)
            clp$find_connected_files (connected_files);
            IF input_block^.input_can_be_echoed AND (connected_files^.echo_count > 0) THEN
              IF input_block^.inherited_input.found THEN
                clp$echo_trace_information ('CLC$ECHO_INCLUDE_$COMMAND_END', ^input_block^.label, NIL,
                      termination_status, status);
              ELSE
                clp$echo_trace_information ('CLC$ECHO_INCLUDE_FILE_END', ^input_block^.label,
                      ^input_block^.input.local_file_name, termination_status, status);
              IFEND;
              status.normal := TRUE;
            IFEND;
*IFEND
          IFEND;
          clp$pop_input_stack (input_block, status);
        IFEND;
      IFEND;
    IFEND;

    IF file_id <> amv$nil_file_identifier THEN
      clp$close_command_file (file_id, opened_executable_file, local_status);
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;
    IFEND;

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

  PROCEDURE [XDCL, #GATE] clp$get_next_scl_proc_line
    (VAR scl_procedure {input, output} : ^clt$scl_procedure;
     VAR line: ^clt$command_line;
     VAR status: ost$status);

    VAR
      entire_procedure: ^clt$input_data,
      getting_first_line: boolean,
      lexical_units: ^clt$lexical_units,
      line_header: ^clt$input_data_line_header,
      line_size: ^clt$command_line_size,
      local_scl_procedure: ^clt$scl_procedure,
      scl_procedure_header: ^clt$scl_procedure_header,
      version: clt$declaration_version;


    status.normal := TRUE;

    getting_first_line := i#current_sequence_position (scl_procedure) = 0;
    local_scl_procedure := scl_procedure;
    RESET local_scl_procedure;
    NEXT scl_procedure_header IN local_scl_procedure;
    IF (scl_procedure_header = NIL) OR (scl_procedure_header^.identifying_first_byte <>
          UPPERVALUE (scl_procedure_header^.identifying_first_byte)) THEN
      version := 0;
    ELSE
      version := scl_procedure_header^.version;
    IFEND;

    IF version = 0 THEN
      NEXT line_size IN scl_procedure;
      IF line_size = NIL THEN
        line := NIL;
        RETURN;
      IFEND;

      NEXT line: [line_size^] IN scl_procedure;
      RETURN;
    IFEND;

    IF getting_first_line THEN
      entire_procedure := #PTR (scl_procedure_header^.entire_procedure, scl_procedure^);
      RESET scl_procedure TO entire_procedure;
    IFEND;

    NEXT line_header IN scl_procedure;
    IF line_header = NIL THEN
      line := NIL;
      RETURN;
    IFEND;

    NEXT line: [line_header^.line_size] IN scl_procedure;
    IF line_header^.number_of_lexical_units > 0 THEN
      NEXT lexical_units: [1 .. line_header^.number_of_lexical_units] IN scl_procedure;
    IFEND;

    IF line_header^.size_of_component_lines_data = 0 THEN
      RETURN;
    IFEND;

    NEXT line_header IN scl_procedure;
    IF line_header = NIL THEN
      line := NIL;
      RETURN;
    IFEND;

    NEXT line: [line_header^.line_size] IN scl_procedure;
    IF line_header^.number_of_lexical_units > 0 THEN
      NEXT lexical_units: [1 .. line_header^.number_of_lexical_units] IN scl_procedure;
    IFEND;

  PROCEND clp$get_next_scl_proc_line;
*IFEND

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

{
{ PURPOSE:
{   This procedure handles SCL input requests directed toward a "non-standard"
{   record access file.  A "standard" record access file is a mass storage
{   file for which the file_access_procedure (FAP), statement_identifier and
{   line_number attributes are undefined.  This procedure handles requests
{   for files that do not meet those criteria.
{

  PROCEDURE [XDCL] clp$get_non_standard_line
    (    line_kind: clt$input_line_kind;
         prompt_string: clt$prompt_string;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
      file_position: amt$file_position,
      first_part_of_line: ^array [1 .. clc$nominal_command_line_size] of cell,
      ignore_data: cell,
      ignore_byte_address: amt$file_byte_address,
      ignore_status: ost$status,
      line_address: amt$file_byte_address,
      line_area: ^SEQ ( * ),
      line_identifier: clt$line_identifier,
      line_text: ^clt$command_line,
*IF NOT $true(osv$unix)
      next_line_area: ^cell,
*ELSE
      next_line_area: ^string(*),
*IFEND
      nominal_line: ^array [1 .. clc$nominal_command_line_size] of cell,
      record_length: amt$max_record_length,
      record_number: amt$file_byte_address,
*IF NOT $true(osv$unix)
      terminal_attributes: array [1 .. 1] of ift$connection_attribute,
*ELSE
      temp_line_area: ^string(*),
      terminal_prompt_string: ift$prompt_string,
      total_count: amt$transfer_count,
*IFEND
      transfer_count: amt$transfer_count;

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

{
{ PURPOSE:
{   This condition handler is established to catch any conditions that occur
{   during the reading of a line.  It is intended to deal with errors caused
{   by a "user supplied" file access procedure (FAP).
{

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

      VAR
        run_time_status: ^ost$status;


      handler_status.normal := TRUE;
      CASE condition.selector OF

      = mmc$segment_access_condition =
        osp$set_status_from_condition ('CL', condition, save_area, status, ignore_status);

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

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          run_time_status := condition_information;
          status := run_time_status^;

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

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

      EXIT clp$get_non_standard_line;

    PROCEND abort_handler;
*IFEND
?? TITLE := 'retry_input_request', EJECT ??

    FUNCTION [INLINE] retry_input_request: boolean;


      retry_input_request := FALSE;

    FUNCEND retry_input_request;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    clp$find_input_block (TRUE, block);
    IF (block = NIL) OR (block^.input.kind <> clc$file_input) THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$get_non_stanard_line', status);
      RETURN;
    IFEND;

    IF block^.input.state = clc$end_of_input THEN
      RETURN;
    IFEND;

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

    IF block^.input.state = clc$update_input THEN
      amp$seek_direct (block^.input.file_id, block^.input.line_address, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF block^.input.line_address_is_for_previous THEN
        amp$get_next (block^.input.file_id, ^ignore_data, 1, transfer_count, ignore_byte_address,
              file_position, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;
    IFEND;
*IFEND

    IF block^.input.interactive_device AND ((block^.input.current_prompt_string.size = 0) OR
*IF NOT $true(osv$unix)
          (prompt_string <> block^.input.current_prompt_string.value (2, * ))) THEN
*ELSE
          (prompt_string <> block^.input.current_prompt_string.value)) THEN
*IFEND
*IF NOT $true(osv$unix)
      terminal_attributes [1].key := ifc$prompt_string;
*IFEND
      IF (STRLENGTH (prompt_string) = clc$same_line_prompt_size) AND (prompt_string = (clc$same_line_prompt))
            THEN
*IF NOT $true(osv$unix)
        terminal_attributes [1].prompt_string.size := clc$same_line_prompt_size;
        terminal_attributes [1].prompt_string.value := clc$same_line_prompt;
*ELSE
        terminal_prompt_string.size := clc$same_line_prompt_size;
        terminal_prompt_string.value := clc$same_line_prompt;
*IFEND
      ELSE
        IF (STRLENGTH (prompt_string) + 1) > ifc$max_prompt_string_size THEN
*IF NOT $true(osv$unix)
          terminal_attributes [1].prompt_string.size := ifc$max_prompt_string_size;
*ELSE
          terminal_prompt_string.size := ifc$max_prompt_string_size;
*IFEND
        ELSE
*IF NOT $true(osv$unix)
          terminal_attributes [1].prompt_string.size := STRLENGTH (prompt_string) + 1;
*ELSE
          terminal_prompt_string.size := STRLENGTH (prompt_string);
*IFEND
        IFEND;
*IF NOT $true(osv$unix)
        terminal_attributes [1].prompt_string.value (1) := ' ';
        terminal_attributes [1].prompt_string.value (2, * ) := prompt_string;
*ELSE
        terminal_prompt_string.value := prompt_string;
*IFEND
      IFEND;
*IF NOT $true(osv$unix)
      clp$set_current_prompt_string (terminal_attributes [1].prompt_string);
*ELSE
      clp$set_current_prompt_string (terminal_prompt_string);
*IFEND
*IF NOT $true(osv$unix)
      IF terminal_attributes [1].prompt_string.value = '' THEN
        terminal_attributes [1].prompt_string.size := 0;
      IFEND;
      ifp$store_term_conn_attributes (block^.input.file_id, terminal_attributes, status);
*IFEND
      IF NOT status.normal THEN
        RETURN;
      IFEND;
*IF $true(osv$unix)
    ELSE
      terminal_prompt_string.value := prompt_string;
      terminal_prompt_string.size := STRLENGTH (prompt_string);
*IFEND
    IFEND;
*IF NOT $true(osv$unix)

    PUSH line_area: [[REP clc$nominal_command_line_size OF char]];
*ELSE
    amp$put_partial (amc_stdout_fid, ^terminal_prompt_string.value,
          terminal_prompt_string.size, ignore_byte_address, amc$continue,
          status);
    PUSH temp_line_area: [clc$nominal_command_line_size];
*IFEND
    line_address := 0;

  /get_line/
    WHILE TRUE DO

    /get_first_part_of_line/
      WHILE TRUE DO
*IF NOT $true(osv$unix)
        amp$get_next (block^.input.file_id, line_area, clc$nominal_command_line_size, transfer_count,
*ELSE
        amp$get_next (block^.input.file_id, temp_line_area, clc$nominal_command_line_size, transfer_count,
*IFEND
              line_address, file_position, status);
        IF status.normal THEN
          EXIT /get_first_part_of_line/;
        ELSEIF retry_input_request () THEN
          osp$generate_message (status, ignore_status);
          CYCLE /get_first_part_of_line/;
        ELSE
          RETURN;
        IFEND;
      WHILEND /get_first_part_of_line/;

*IF $true(osv$unix)
      line_area := #SEQ(temp_line_area^);

*IFEND
      IF (file_position < amc$eor) AND (block^.input.line_layout.physical_line_size > #SIZE (line_area^)) THEN
        RESET line_area;
        NEXT nominal_line IN line_area;
        PUSH line_area: [[REP block^.input.line_layout.physical_line_size OF char]];
        RESET line_area;
        NEXT first_part_of_line IN line_area;
        first_part_of_line^ := nominal_line^;
*IF NOT $true(osv$unix)
        NEXT next_line_area IN line_area;
*ELSE
        NEXT next_line_area: [block^.input.line_layout.physical_line_size -
              clc$nominal_command_line_size] IN line_area;
        total_count := transfer_count;
*IFEND
        record_length := clc$nominal_command_line_size;

        amp$get_partial (block^.input.file_id, next_line_area,
              block^.input.line_layout.physical_line_size - clc$nominal_command_line_size, record_length,
              transfer_count, ignore_byte_address, file_position, amc$no_skip, status);
        IF NOT status.normal THEN
          IF retry_input_request () THEN
            osp$generate_message (status, ignore_status);
            CYCLE /get_line/;
          IFEND;
          RETURN;
        IFEND;
*IF NOT $true(osv$unix)
        transfer_count := record_length;
*ELSE
        transfer_count := total_count + transfer_count;
*IFEND
      IFEND;

      IF file_position < amc$eor THEN
*IF NOT $true(osv$unix)
        osp$set_status_abnormal ('CL', cle$line_too_long, block^.input.local_file_name, status);
*ELSE
        osp$set_status_abnormal ('CL', cle$line_too_long, '', status);
        osp$append_status_file (osc$status_parameter_delimiter, block^.input.local_file_name, status);
*IFEND
        RETURN;
      IFEND;

      IF file_position > amc$eor THEN

        IF block^.input.interactive_device AND (block^.previous_block^.kind = clc$task_block) AND
              (block^.previous_block^.task_kind = clc$job_monitor_task) THEN
          IF file_position = amc$eop THEN
            osp$set_status_abnormal ('CL', cle$interactive_eop_ignored, '', status);
          ELSE
            osp$set_status_abnormal ('CL', cle$interactive_eoi_ignored, '', status);
          IFEND;
          osp$generate_message (status, ignore_status);
          CYCLE /get_line/;
        IFEND;

        line_text := NIL;
      ELSE
        clp$layout_data_line (block^.input.local_file_name, transfer_count, block^.input.line_layout,
              line_area, line_text, line_identifier, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        record_number := block^.input.record_number + 1;
        IF line_kind = clc$command_line THEN
          line_identifier.byte_address := line_address;
          line_identifier.record_number := record_number;
        ELSE
          line_identifier.byte_address := block^.input.line_address;
          line_identifier.record_number := block^.input.record_number;
        IFEND;
      IFEND;

      EXIT /get_line/;
    WHILEND /get_line/;

    clp$set_input_line (line_kind, line_text, line_identifier, record_number, line_address);

  PROCEND clp$get_non_standard_line;
?? TITLE := 'clp$get_line_from_command_file', EJECT ??
*copyc clh$get_line_from_command_file

  PROCEDURE [XDCL, #GATE] clp$get_line_from_command_file
    (    prompt_string: clt$prompt_string;
     VAR line: ^clt$command_line;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
*IF NOT $true(osv$unix)
      context: ^ost$ecp_exception_context,
*IFEND
      local_status: ost$status;

    status.normal := TRUE;
*IF NOT $true(osv$unix)
    context := NIL;
*IFEND
    local_status.normal := TRUE;
    line := NIL;

  /main/
    BEGIN
      clp$find_input_block (TRUE, block);
      IF block = NIL THEN
        osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$get_line_from_command_file',
              local_status);
        EXIT /main/;
      IFEND;

      IF (block^.input.kind = clc$line_input) OR (block^.input.state = clc$end_of_input) THEN
        EXIT /main/;
      IFEND;

      REPEAT
        block^.input.get_line^ (clc$data_line, prompt_string, local_status);
*IF NOT $true(osv$unix)
        IF NOT local_status.normal THEN
          IF context = NIL THEN
            PUSH context;
            context^ := osv$initial_exception_context;
          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);
*ELSE
      UNTIL local_status.normal;
*IFEND

      IF (NOT local_status.normal) OR (block^.input.state = clc$end_of_input) THEN
        EXIT /main/;
      IFEND;

      line := block^.input.data_line.text;
    END /main/;

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

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

  PROCEDURE [XDCL, #GATE] clp$get_data_line
    (    prompt_string: string ( * );
     VAR line: ost$string;
     VAR got_line: boolean;
     VAR status: ost$status);

    VAR
      line_ptr: ^clt$command_line,
      local_status: ost$status;


    status.normal := TRUE;
    local_status.normal := TRUE;
    got_line := FALSE;
    line.size := 0;
    line.value := '';

  /main/
    BEGIN
      clp$get_line_from_command_file (prompt_string, line_ptr, local_status);
      IF NOT (local_status.normal AND (line_ptr <> NIL)) THEN
        EXIT /main/;
      IFEND;

      got_line := TRUE;
      IF STRLENGTH (line_ptr^) > osc$max_string_size THEN
        line.size := osc$max_string_size;
      ELSE
        line.size := STRLENGTH (line_ptr^);
      IFEND;
      line.value := line_ptr^ (1, line.size);
    END /main/;

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

  PROCEND clp$get_data_line;
*IFEND
?? TITLE := 'clp$get_non_standard_cmnd_line', EJECT ??

  PROCEDURE [XDCL] clp$get_non_standard_cmnd_line
    (VAR parse: clt$parse_state;
     VAR end_of_input: boolean;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
      command_prompt_ptr: ^clt$prompt_string,
      command_prompt_string: ift$prompt_string,
      continuation_line: ^clt$command_line,
      continuation_line_size: integer,
*IF $true(osv$unix)
      handler_stat: boolean,
*IFEND
      line: ^clt$command_line,
      line_continued: boolean,
      line_size: integer;

?? NEWTITLE := 'terminate_handler', EJECT ??

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


      IF (condition.selector = ifc$interactive_condition) AND
            (condition.interactive_condition = ifc$terminate_break) THEN
*ELSE
      (    signal_no: integer;
           code: integer;
           p_sigcontext: ^cyt$mips_sigcontext);

      VAR
        local_status: ost$status;


      CASE signal_no OF
      { pmc$block_exit_processing    -    block exit
      = -1 =
*IFEND
        osp$set_status_abnormal ('CL', cle$command_line_cancelled, '', status);
*IF NOT $true(osv$unix)
        osp$generate_output_message (status, handler_status);
        handler_status.normal := TRUE;
*ELSE
        osp$generate_message (status, local_status);
*IFEND
        clp$set_input_line (clc$command_line, ^line^ (1, 0), block^.line_identifier,
              block^.input.record_number, block^.input.line_address);
        status.normal := TRUE;
        end_of_input := FALSE;
        parse := block^.line_parse;
*IF NOT $true(osv$unix)
        EXIT clp$get_non_standard_cmnd_line;
      IFEND;

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

    PROCEND terminate_handler;
?? OLDTITLE, EJECT ??
*IF NOT $true(osv$unix)
    VAR
      context: ^ost$ecp_exception_context;
*IFEND

    status.normal := TRUE;
*IF NOT $true(osv$unix)
    context := NIL;
*IFEND
    end_of_input := TRUE;

    clp$find_input_block (TRUE, block);
    IF block = NIL THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$get_non_standard_cmnd_line', status);
      RETURN;
    IFEND;

    IF block^.input.state = clc$end_of_input THEN
      RETURN;
    IFEND;

    IF block^.input.prompting_input THEN
      command_prompt_string.size := clc$same_line_prompt_size;
      command_prompt_string.value := clc$same_line_prompt;
      command_prompt_ptr := ^command_prompt_string.value (1, clc$same_line_prompt_size);
    ELSE
      command_prompt_string.size := block^.input.base_prompt_string.size + 1;
      command_prompt_string.value := block^.input.base_prompt_string.value;
      ?IF clc$compiling_for_test_harness THEN
        command_prompt_string.value (command_prompt_string.size) := '!';
      ?ELSE
        command_prompt_string.value (command_prompt_string.size) := '/';
      ?IFEND;
      command_prompt_ptr := ^command_prompt_string.value (2, command_prompt_string.size - 1);
    IFEND;

    REPEAT
      clp$get_non_standard_line (clc$command_line, command_prompt_ptr^, status);
*IF NOT $true(osv$unix)
      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
    UNTIL status.normal;
*IFEND
    IF (NOT status.normal) OR (block^.input.state = clc$end_of_input) THEN
      RETURN;
    IFEND;
    line := block^.input.line.text;

*IF $true(osv$unix)
    IF (STRLENGTH (line^) < 1) OR (line^ (STRLENGTH (line^), 1) <> '\') THEN
*ELSE
    IF (STRLENGTH (line^) < 2) OR (line^ (STRLENGTH (line^) - 1, 2) <> '..') THEN
*IFEND
      parse := block^.line_parse;
      end_of_input := FALSE;
      RETURN;
    IFEND;

    IF block^.input.prompting_input THEN
      command_prompt_string.size := clc$cont_same_line_prompt_size;
      command_prompt_string.value := clc$continued_same_line_prompt;
      command_prompt_ptr := ^command_prompt_string.value (1, clc$cont_same_line_prompt_size);
    ELSE
      ?IF clc$compiling_for_test_harness THEN
        command_prompt_string.value (command_prompt_string.size, 3) := '..!';
      ?ELSE
        command_prompt_string.value (command_prompt_string.size, 3) := '../';
      ?IFEND;
      command_prompt_string.size := command_prompt_string.size + 2;
      command_prompt_ptr := ^command_prompt_string.value (2, command_prompt_string.size - 1);
    IFEND;
*IF $true(osv$unix)
    line_size := STRLENGTH (line^) - 1;
    WHILE (line_size > 0) AND (line^ (line_size) = '\') DO
*ELSE
    line_size := STRLENGTH (line^) - 2;
    WHILE (line_size > 0) AND (line^ (line_size) = '.') DO
*IFEND
      line_size := line_size - 1;
    WHILEND;

    IF (block^.input.kind = clc$file_input) AND block^.input.interactive_device THEN
*IF NOT $true(osv$unix)
      osp$establish_condition_handler (^terminate_handler, FALSE);
*ELSE
{ The following code SHOULD simulate a condition handler for terminate break -
{ a block exit handler is established around the call to clp$get_non_standard_
{ line. If a terminate break is entered during that request, we'll catch it
{ after the fact in the following REPEAT loop and do the cleanup that would
{ normally happen for a terminate break. The condition (signal) is eaten.

      handler_stat := #establish_condition_handler (-1, ^terminate_handler);
{     IF NOT handler_stat THEN
{       stringrep(ps_line,ps_length,'Handler status was ',handler_stat);
{       print_string(ps_line,ps_length);
{     IFEND;
*IFEND
    IFEND;

    REPEAT
      REPEAT
        clp$get_non_standard_line (clc$command_continuation_line, command_prompt_ptr^, status);
*IF NOT $true(osv$unix)
        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
      IF osc_sigint IN osv$signal THEN
        osv$signal := osv$signal - $ost$signals [osc_sigint];
        RETURN;
      IFEND;
      UNTIL status.normal;
      handler_stat := #disestablish_condition_handler (-1);
*IFEND
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      continuation_line := block^.input.data_line.text;
      IF continuation_line = NIL THEN
        osp$set_status_abnormal ('CL', cle$expecting_continuation_line, '', status);
        RETURN;
      IFEND;
      continuation_line_size := STRLENGTH (continuation_line^);
*IF $true(osv$unix)
      line_continued := (continuation_line_size >= 1) AND (continuation_line^
            (continuation_line_size, 1) = '\');
      IF line_continued THEN
        continuation_line_size := continuation_line_size - 1;
        WHILE (continuation_line_size > 0) AND (continuation_line^ (continuation_line_size) = '\') DO
*ELSE
      line_continued := (continuation_line_size >= 2) AND (continuation_line^
            (continuation_line_size - 1, 2) = '..');
      IF line_continued THEN
        continuation_line_size := continuation_line_size - 2;
        WHILE (continuation_line_size > 0) AND (continuation_line^ (continuation_line_size) = '.') DO
*IFEND
          continuation_line_size := continuation_line_size - 1;
        WHILEND;
      IFEND;
      IF (line_size + continuation_line_size) > clc$max_command_line_size THEN
        osp$set_status_abnormal ('CL', cle$continued_line_too_long, '', status);
        RETURN;
      IFEND;
      clp$append_continuation_line (line_size, continuation_line_size, line);
      line_size := line_size + continuation_line_size;
    UNTIL NOT line_continued;

    clp$set_input_line (clc$command_line, line, block^.line_identifier, block^.input.record_number,
          block^.input.line_address);

    parse := block^.line_parse;
    end_of_input := FALSE;

  PROCEND clp$get_non_standard_cmnd_line;
?? TITLE := 'preprocess_command_line', EJECT ??

  PROCEDURE [XDCL] clp$preprocess_command_line
    (    line_preprocessor_descriptor: clt$utility_line_preproc_desc;
         line: ^clt$command_line;
         interactive_file: boolean;
     VAR edited_line: ^clt$command_line;
     VAR status: ost$status);

    VAR
*IF NOT $true(osv$unix)
      callers_save_area: ^ost$stack_frame_save_area,
*IFEND
      current_block: ^clt$block,
*IF NOT $true(osv$unix)
      line_preprocessor: clt$utility_line_preprocessor,
      loaded_address: pmt$loaded_address;
*ELSE
      line_preprocessor: clt$utility_line_preprocessor;
*IFEND

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

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

      VAR
        line_preprocessor_name: pmt$program_name;


      IF (condition.selector = pmc$system_conditions) AND (($pmt$system_conditions
            [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
            pmc$environment_specification, pmc$invalid_segment_ring_0, pmc$out_call_in_return] *
            condition.system_conditions) <> $pmt$system_conditions []) THEN
        IF save_area^.minimum_save_area.a2_previous_save_area = callers_save_area THEN
          IF line_preprocessor_descriptor.call_method = clc$unlinked_call THEN
            line_preprocessor_name := line_preprocessor_descriptor.procedure_name;
          ELSE
            line_preprocessor_name := '';
          IFEND;
          osp$set_status_abnormal ('CL', cle$unable_to_call_preprocessor, line_preprocessor_name, status);
          EXIT clp$preprocess_command_line;
        IFEND;
      IFEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

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

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

    CASE line_preprocessor_descriptor.call_method OF
    = clc$unspecified_call =
      RETURN;
    = clc$linked_call =
      line_preprocessor := line_preprocessor_descriptor.proc;
*IF NOT $true(osv$unix)
    = clc$unlinked_call =
      pmp$load (line_preprocessor_descriptor.procedure_name, pmc$procedure_address, loaded_address, status);
      IF NOT status.normal THEN
        osp$set_status_abnormal ('CL', cle$unable_to_call_preprocessor,
              line_preprocessor_descriptor.procedure_name, status);
        RETURN;
      IFEND;
      #CONVERT_POINTER_TO_PROCEDURE (loaded_address.pointer_to_procedure, line_preprocessor);
*IFEND
    ELSE

{ Should never get here.

      osp$set_status_abnormal ('CL', cle$unable_to_call_preprocessor, '', status);
      RETURN;
    CASEND;

    clp$find_current_block (current_block);

*IF NOT $true(osv$unix)
    callers_save_area := #PREVIOUS_SAVE_AREA ();
    #SPOIL (callers_save_area);
    osp$establish_condition_handler (^bad_line_preprocessor_handler, FALSE);
*IFEND
    line_preprocessor^ (line, interactive_file, (current_block^.interpreter_mode = clc$interpret_mode),
          edited_line, status);
*IF NOT $true(osv$unix)
    osp$disestablish_cond_handler;
*IFEND
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF edited_line <> NIL THEN
      edited_line := ^edited_line^ (1, clp$trimmed_string_size (edited_line^));
    IFEND;

  PROCEND clp$preprocess_command_line;
?? TITLE := 'clp$get_command_line', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$get_command_line
    (VAR parse: clt$parse_state;
     VAR end_of_input: boolean;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
*IF NOT $true(osv$unix)
      context: ^ost$ecp_exception_context,
*IFEND
      edited_line: ^clt$command_line;


    status.normal := TRUE;
*IF NOT $true(osv$unix)
    context := NIL;
*IFEND
    end_of_input := TRUE;

    clp$find_input_block (TRUE, block);
    IF block = NIL THEN
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$get_command_line', status);
      RETURN;
    IFEND;

    IF (block^.input.kind = clc$line_input) OR (block^.input.state = clc$end_of_input) THEN
      RETURN;
    IFEND;

    WHILE TRUE DO
      REPEAT
        block^.input.get_command_line^ (parse, end_of_input, status);
*IF NOT $true(osv$unix)
        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
      UNTIL status.normal;

*IFEND
      IF (NOT status.normal) OR end_of_input OR block^.input.prompting_input OR
            (NOT block^.line_preprocessor_specified) THEN
        RETURN;
      IFEND;

      clp$preprocess_command_line (block^.associated_utility^.line_preprocessor, parse.text,
            (block^.input.kind = clc$file_input) AND block^.input.interactive_device, edited_line, status);
      IF (NOT status.normal) OR (edited_line = NIL) THEN
        RETURN;
      IFEND;

      IF edited_line^ <> '' THEN
        clp$set_input_line (clc$command_line, edited_line, block^.line_identifier, block^.input.record_number,
              block^.input.line_address);
        parse := block^.line_parse;
        RETURN;
      IFEND;
    WHILEND;

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

  PROCEDURE [XDCL, #GATE] clp$get_semicolon_after_command
    (VAR semicolon_after_command: boolean;
     VAR status: ost$status);

    VAR
      input_block: ^clt$block;


    status.normal := TRUE;
    clp$find_external_input_block (input_block);
    semicolon_after_command := (input_block <> NIL) AND (input_block^.line_parse.previous_non_space_unit.
          kind = clc$lex_semicolon);

  PROCEND clp$get_semicolon_after_command;
?? TITLE := 'clp$push_interactive_input', EJECT ??
*copyc clh$push_interactive_input

  PROCEDURE [XDCL, #GATE] clp$push_interactive_input
    (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);


      clp$close_command_file (file_id, opened_executable_file, handler_status);
      handler_status.normal := TRUE;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    VAR
      caller_id: ost$caller_identifier,
      can_be_echoed: boolean,
      device_class: rmt$device_class,
      dummy_segment: ^SEQ ( * ),
      file_has_fap: boolean,
      file_id: amt$file_identifier,
      ignore_file_contents: clt$file_contents,
      ignore_path_handle_name: fst$path_handle_name,
      ignore_ring_attributes: amt$ring_attributes,
      input_block: ^clt$block,
      job_mode: jmt$job_mode,
      line_layout: clt$line_layout,
      local_status: ost$status,
      opened_executable_file: boolean,
      utility_name: ost$name;


    status.normal := TRUE;
    local_status.normal := TRUE;
    #CALLER_ID (caller_id);

    input_block := NIL;
    file_id := amv$nil_file_identifier;
    #SPOIL (file_id);

    osp$establish_block_exit_hndlr (^abort_handler);

  /push_input/
    BEGIN
      pmp$get_job_mode (job_mode, local_status);
      IF NOT local_status.normal THEN
        EXIT /push_input/;
      IFEND;
      IF (job_mode = jmc$batch) AND (NOT jmp$system_job ()) THEN
        osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$push_interactive_input', local_status);
        EXIT /push_input/;
      IFEND;

      clp$access_command_file (clc$include_file, caller_id.ring,
            clv$standard_files [clc$sf_command_file].path_handle_name, file_id, dummy_segment,
            opened_executable_file, can_be_echoed, line_layout, ignore_file_contents, ignore_ring_attributes,
            file_has_fap, device_class, ignore_path_handle_name, local_status);
      IF NOT local_status.normal THEN
        EXIT /push_input/;
      IFEND;

      clp$find_input_block (TRUE, input_block);
      IF (input_block <> NIL) AND (input_block^.associated_utility <> NIL) THEN
        utility_name := input_block^.associated_utility^.label;
      ELSE
        utility_name := osc$null_name;
      IFEND;
      input_block := NIL;

      clp$push_input_file_block (clv$standard_files [clc$sf_command_file].path_handle_name, file_id,
            utility_name, '', can_be_echoed, line_layout, device_class, file_has_fap, FALSE,
            input_block);
    END /push_input/;

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

    osp$disestablish_cond_handler;

  PROCEND clp$push_interactive_input;
?? TITLE := 'clp$pop_interactive_input', EJECT ??
*copyc clh$pop_interactive_input

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

    VAR
      file_id: amt$file_identifier,
      input_block: ^clt$block,
      local_status: ost$status;


    status.normal := TRUE;
    local_status.normal := TRUE;

  /pop_input/
    BEGIN
      clp$find_current_block (input_block);
      IF (input_block = NIL) OR (input_block^.kind <> clc$input_block) OR
            (input_block^.input.kind <> clc$file_input) OR (input_block^.input.local_file_name <>
            clv$standard_files [clc$sf_command_file].path_handle_name) OR
            (NOT input_block^.input.interactive_device) THEN
        osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$pop_interactive_input', local_status);
        EXIT /pop_input/;
      IFEND;
      file_id := input_block^.input.file_id;
      clp$pop_input_stack (input_block, local_status);
      IF NOT local_status.normal THEN
        EXIT /pop_input/;
      IFEND;
      clp$close_command_file (file_id, FALSE, local_status);
    END /pop_input/;

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

  PROCEND clp$pop_interactive_input;
*IFEND

MODEND clm$input_procedures;
