?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Rewind Command' ??
MODULE clm$rewind_command;

{
{ PURPOSE:
{   This module contains the processor for the rewind command.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ame$lfn_program_actions
*copyc clt$parameter_list
*copyc ost$status
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$rewind
*copyc amv$nil_file_identifier
*copyc bap$sl_rewind_file_command
*copyc clp$convert_string_to_file
*copyc clp$evaluate_parameters
*copyc fsp$close_file
*copyc fsp$open_file
*copyc osp$append_status_parameter
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc rmp$get_device_class

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

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

{ PROCEDURE (osm$rewf) rewind_file, rewind_files, rewf (
{   files, file, f: list of file = $required
{   status)

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

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 4] of clt$pdt_parameter_name,
      parameters: array [1 .. 2] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$list_type_qualifier,
        element_type_spec: record
          header: clt$type_specification_header,
        recend,
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [88, 11, 18, 13, 17, 0, 998],
    clc$command, 4, 2, 1, 0, 0, 0, 2, 'OSM$REWF'], [
    ['F                              ',clc$abbreviation_entry, 1],
    ['FILE                           ',clc$alias_entry, 1],
    ['FILES                          ',clc$nominal_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 19, clc$required_parameter,
  0, 0],
{ PARAMETER 2
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$list_type], [3, 1, clc$max_list_size, FALSE],
      [[1, 0, clc$file_type]]
    ],
{ PARAMETER 2
    [[1, 0, clc$status_type]]];

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

    CONST
      p$files = 1,
      p$status = 2;

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

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

      fsp$close_file (file_id, handler_status);

      handler_status.normal := TRUE;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    VAR
      current_file: ^clt$data_value,
      device_assigned: boolean,
      device_class: rmt$device_class,
      file: clt$file,
      file_attachment: array [1 .. 2] of fst$attachment_option,
      file_attributes: array [1 .. 1] of amt$get_item,
      file_exists: boolean,
      file_id: amt$file_identifier,
      file_previously_opened: boolean,
      file_set_position_changed: boolean,
      ignore_contains_data: boolean,
      ignore_status: ost$status,
      tape_file_attributes: array [1 .. 1] of amt$get_item;

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

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

    current_file := pvt [p$files].value;

  /rewind_files/
    WHILE current_file <> NIL DO

      file_attributes [1].key := amc$null_attribute;

      file_attachment [1].selector := fsc$create_file;
      file_attachment [1].create_file := FALSE;
      file_attachment [2].selector := fsc$access_and_share_modes;
      file_attachment [2].access_modes.selector := fsc$permitted_access_modes;
      file_attachment [2].share_modes.selector := fsc$required_share_modes;

      amp$get_file_attributes (current_file^.element_value^.file_value^, file_attributes,
            file_exists, file_previously_opened, ignore_contains_data, status);
      IF NOT status.normal THEN
        EXIT /rewind_files/;
      IFEND;
      IF NOT file_exists THEN
        osp$set_status_abnormal ('CL', ame$file_not_known, current_file^.element_value^.file_value^, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'REWIND_FILE', status);
        EXIT /rewind_files/;
      IFEND;
      IF file_previously_opened THEN
        rmp$get_device_class (current_file^.element_value^.file_value^, device_assigned,
              device_class, status);
        IF NOT status.normal THEN
          EXIT /rewind_files/;
        IFEND;
        IF device_assigned AND (device_class = rmc$magnetic_tape_device) THEN
          tape_file_attributes [1].key := amc$label_type;
          amp$get_file_attributes (current_file^.element_value^.file_value^, tape_file_attributes,
                file_exists, file_previously_opened, ignore_contains_data, status);
          IF NOT status.normal THEN
            EXIT /rewind_files/;
          IFEND;
          IF tape_file_attributes [1].label_type = amc$labelled THEN
            clp$convert_string_to_file (current_file^.element_value^.file_value^, file, status);
            IF NOT status.normal THEN
              EXIT /rewind_files/;
            IFEND;
            bap$sl_rewind_file_command (file.local_file_name, status);
            IF NOT status.normal THEN
              EXIT /rewind_files/;
            ELSE
              current_file := current_file^.link;
              CYCLE /rewind_files/;
            IFEND;
          IFEND;
        IFEND;
        fsp$open_file (current_file^.element_value^.file_value^, amc$record, ^file_attachment, NIL, NIL, NIL,
              NIL, file_id, status);
        IF NOT status.normal THEN
          EXIT /rewind_files/;
        IFEND;
        amp$rewind (file_id, osc$wait, status);
        IF status.normal THEN
          fsp$close_file (file_id, status);
        ELSE
          fsp$close_file (file_id, ignore_status);
        IFEND;
        IF NOT status.normal THEN
          EXIT /rewind_files/;
        IFEND;
      IFEND;
      current_file := current_file^.link;
    WHILEND /rewind_files/;

    osp$disestablish_cond_handler;

  PROCEND clp$rewind_command;

MODEND clm$rewind_command;
