
  PROCEDURE {INLINE} bai$process_block_information
    (    file_identifier: amt$file_identifier;
         label_type: amt$file_label_type;
         operation: amt$fap_operation;
         block_type: bat$tape_block_type;
         tape_error_options: amt$tape_error_options;
         tape_failure_modes: amt$tape_failure_modes;
     VAR reissue_read_request: boolean;
     VAR volume_position: amt$volume_position;
     VAR status: ost$status);

?? RIGHT := 110 ??
?? PUSH (LISTEXT := ON) ??

{ The purpose of this routine is to process the read block information and
{ use the tape error options to determine how much, if any of the data
{ returned is any good for the application.

*copy bah$inline_proc_documentation

    CONST
      bc = 1;

    VAR
      ansi_file_attrib: ^array [bc .. bc] of fst$attachment_option,
      error_action: bat$error_actions,
      returned_attributes: fst$tla_returned_attributes,
      label_group: fst$ansi_label_kinds,
      request_status: ost$status,
      started_after_label_group: boolean;

?? NEWTITLE := '      validate_block_count', EJECT ??

    PROCEDURE validate_block_count
      (    label: string (4));

      VAR
        error_status: ost$status,
        ignore_status: ost$status,
        logset: pmt$ascii_logset;

      IF (ansi_file_attrib^ [bc].tape_attachment.tape_block_count <> 0) AND
            (ansi_file_attrib^ [bc].tape_attachment.tape_block_count <>
            gfi^.positioning_info.block_info.block_number) THEN
        osp$set_status_condition (ame$label_block_count_mismatch, error_status);
        osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, error_status);
        osp$append_status_integer (osc$status_parameter_delimiter,
              gfi^.positioning_info.block_info.block_number, 10, FALSE, error_status);
        osp$append_status_parameter (osc$status_parameter_delimiter, label, error_status);
        osp$append_status_integer (osc$status_parameter_delimiter,
              ansi_file_attrib^ [bc].tape_attachment.tape_block_count, 10, FALSE, error_status);
      IFEND;
      osp$generate_error_message (error_status, ignore_status);
      logset := $pmt$ascii_logset [pmc$job_log];
      osp$generate_log_message (logset, error_status, ignore_status);

    PROCEND validate_block_count;
?? OLDTITLE, EJECT ??

    reissue_read_request := FALSE;
    volume_position := amc$after_data_block;

{
{ The following are descriptions of the various error actions.
{
{       = amc$accept_erroneous_block =
{
{ This option causes all I/O errors to be reported to the application.
{ Data is transferred as best as can be accomplished.
{
{       = amc$ignore_erroneous_block =
{
{ This option causes any blocks with unrecoverable errors to be ignored.
{ The action will be as if the block did not appear on the tape at all,
{ except for possibly trashing the users working storage area.
{
{       = amc$terminate_file_access =
{
{ When this option is selected, any unrecovered tape I/O error will be a fatal
{ error.
{

    CASE block_type OF

    = bac$good_data_block =
    = bac$error_data_block =
      CASE tape_error_options.error_action OF
      = amc$accept_erroneous_block =
        amp$set_file_instance_abnormal (file_identifier, ame$accept_bad_block, operation, ' ', status);
        bai$append_tape_error (file_identifier, tape_failure_modes, status);
        tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
      = amc$ignore_erroneous_block =
        reissue_read_request := TRUE;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$unrecovered_read_error, operation, ' ', status);
        bai$append_tape_error (file_identifier, tape_failure_modes, status);
        tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
      CASEND;
    = bac$error_without_data =
      CASE tape_error_options.error_action OF
      = amc$ignore_erroneous_block =
        IF (amc$tfm_device_not_ready IN tape_failure_modes) OR
              (amc$tfm_agc_gains_not_set IN tape_failure_modes) OR
              (amc$tfm_hardware_failure IN tape_failure_modes) THEN
          ;
        ELSE
          reissue_read_request := TRUE;
          RETURN; {----->
        IFEND;
      ELSE
      CASEND;
      amp$set_file_instance_abnormal (file_identifier, ame$unrecovered_read_error, operation, ' ', status);
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
      tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
    = bac$density_mismatch =
      amp$set_file_instance_abnormal (file_identifier, ame$tape_density_mismatch, operation, ' ', status);
      tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
    = bac$read_past_phys_eot =
      amp$set_file_instance_abnormal (file_identifier, ame$motion_past_phys_eot, operation, ' ', status);
      tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
    = bac$tapemark =
      IF label_type = amc$unlabelled THEN
        bai$check_tapemark (file_identifier, volume_position, request_status);
        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
        IF volume_position = amc$eov THEN
          bai$advance_volume (file_identifier, volume_position, status);
          tape_descriptor^.volume_position := volume_position;
          IF NOT status.normal OR (volume_position = amc$eov) THEN
            RETURN; {----->
          IFEND;
          reissue_read_request := TRUE;
        IFEND;
      ELSEIF label_type = amc$labelled THEN
        started_after_label_group := sl_after_label_group (tape_descriptor^.labeled_volume_position);
        sl_read_tape_labels (file_identifier, label_group, status);
        IF NOT status.normal THEN
          IF started_after_label_group THEN
            tape_descriptor^.labeled_volume_position := bac$lvp_end_of_file_set;
            volume_position := amc$after_tapemark;
            RETURN; {----->
          ELSE
            CASE status.condition OF
            = ame$invalid_tape_label = {Allow: * data}
              sl_advance_tapemark (file_identifier, amc$backward, 1, status);
              IF status.normal THEN
                sl_advance_tapemark (file_identifier, amc$forward, 1, status);
                volume_position := amc$after_tapemark;
                RETURN; {----->
              IFEND;
            = ame$unexpected_tapemark = {Each embedded tapemark returns EOI status}
              sl_advance_tapemark (file_identifier, amc$backward, 2, status);
              IF status.normal THEN
                sl_advance_tapemark (file_identifier, amc$forward, 1, status);
                volume_position := amc$after_tapemark;
                RETURN; {----->
              IFEND;
            ELSE
            CASEND;
          IFEND;
        IFEND;
        IF status.normal THEN
          PUSH ansi_file_attrib;
          ansi_file_attrib^ [bc].selector := fsc$tape_attachment;
          ansi_file_attrib^ [bc].tape_attachment.selector := fsc$tape_block_count;
          fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_last_ansi_file_accessed,
                ansi_file_attrib^, returned_attributes, status);
          IF status.normal THEN
            IF fsc$tape_block_count IN returned_attributes THEN
              IF fsc$ansi_eof1_label_kind IN label_group THEN
                validate_block_count ('EOF1');
              ELSEIF fsc$ansi_eov1_label_kind IN label_group THEN
                validate_block_count ('EOV1');
              IFEND;
            IFEND;
            IF fsc$ansi_eof1_label_kind IN label_group THEN
              volume_position := amc$after_tapemark;
              IF fsc$tape_block_count IN returned_attributes THEN
                state_info^.eof1_block_count := ansi_file_attrib^ [bc].tape_attachment.tape_block_count;
              ELSE
                state_info^.eof1_block_count := 0;
              IFEND;
              IF state_info^.eof1_block_count = 0 THEN
                gfi^.positioning_info.block_info.block_number := 1;
              ELSE
                gfi^.positioning_info.block_info.block_number := state_info^.eof1_block_count;
              IFEND;
            ELSEIF fsc$ansi_eov1_label_kind IN label_group THEN
              reissue_read_request := TRUE;
              volume_position := amc$bov;
              sl_close_label_volume (file_identifier, status);
              IF (NOT status.normal) AND (status.condition = ame$tape_end_of_volume_list) THEN
                IF fsc$tape_block_count IN returned_attributes THEN
                  state_info^.eof1_block_count := ansi_file_attrib^ [bc].tape_attachment.tape_block_count;
                ELSE
                  state_info^.eof1_block_count := 0;
                IFEND;
                IF state_info^.eof1_block_count = 0 THEN
                  gfi^.positioning_info.block_info.block_number := 1;
                ELSE
                  gfi^.positioning_info.block_info.block_number := state_info^.eof1_block_count;
                IFEND;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      ELSE { label_type =  non  standard labelled. }
        volume_position := amc$after_tapemark;
      IFEND;
    ELSE
      amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
            'Unknown block_type in bai$process_block_description.', status);
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
      tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
    CASEND;

  PROCEND bai$process_block_information;

*copyc amt$call_block
*copyc amt$file_identifier
*copyc amt$tape_error_options
*copyc amt$volume_position
*copyc bai$advance_volume
*copyc fsp$get_tape_label_attributes
*copyc ost$status
?? POP ??
