?? NEWTITLE := 'BASIC ACCESS METHODS: FILE ATTRIBUTE MANAGER' ??
MODULE fmm$file_attribute_manager;
?? RIGHT := 110 ??

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$job_pageable
*copyc oss$job_paged_literal
*copyc amc$fap_request_codes
*copyc fmc$maximum_file_label_size
*copyc fsc$local
*copyc osc$base_exception
*copyc ame$attribute_validation_errors
*copyc ame$improper_file_id
*copyc ame$lfn_program_actions
*copyc ame$ring_validation_errors
*copyc cle$ecc_lexical
*copyc fme$file_management_errors
*copyc fse$get_info_validation_errors
*copyc fse$open_validation_errors
*copyc ose$heap_full_exceptions
*copyc pfe$error_condition_codes
*copyc pfe$internal_error_conditions
*copyc amt$add_to_attributes
*copyc amt$file_access_selections
*copyc amt$file_organization_set
*copyc amt$loading_factor
*copyc amt$lock_expiration_time
*copyc amt$log_residence
*copyc amt$logging_options
*copyc bat$system_file_attributes
*copyc clt$file
*copyc fmt$cd_attachment_options
*copyc fmt$file_attribute_keys
*copyc fmt$file_label
*copyc fmt$label_headers
*copyc fmt$open_cleanup_work_list
*copyc fmt$static_label_header
*copyc fst$goi_object_information
*copyc fst$retention
*copyc gft$system_file_identifier
*copyc jmt$system_label_info_length
*copyc ost$caller_identifier
*copyc ost$segment_access_control
*copyc pft$attached_permanent_file_id
*copyc rmt$device_class
?? POP ??
*copyc baf$task_file_entry_p
*copyc amp$set_file_instance_abnormal
*copyc avp$ring_min
*copyc bap$set_evaluated_file_abnormal
*copyc clp$check_name_for_path_handle
*copyc clp$convert_file_ref_to_string
*copyc clp$convert_integer_to_string
*copyc dmp$fetch_eoi
*copyc dmp$get_tape_volume_information
*copyc dmp$set_file_limit
*copyc fmp$catalog_system_file_label
*copyc fmp$extract_dynamic_setfa_attrs
*copyc fmp$get_cycle_description
*copyc fmp$get_label_attributes
*copyc fmp$locate_cd_via_path_handle
*copyc fmp$locate_cycle_description
*copyc fmp$merge_setfa_entries
*copyc fmp$put_label_attributes
*copyc fmp$unlock_path_table
*copyc fsp$adjust_tape_defaults
*copyc fsp$convert_file_contents
*copyc fsp$convert_to_old_contents
*copyc fsp$expand_file_label
*copyc fsp$path_element
*copyc fsp$set_evaluated_file_abnormal
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$fetch_locked_variable
*copyc osp$increment_locked_variable
*copyc osp$set_job_signature_lock
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc osp$test_sig_lock
*copyc pfp$compute_checksum
*copyc pfp$convert_fs_to_pft$path
*copyc pfp$r3_get_object_information
*copyc pfp$r3_save_released_file_label
*copyc pfp$save_file_label
*copyc amv$aam_file_organizations
*copyc fmv$global_file_information
*copyc fmv$static_label_header
*copyc fmv$system_file_attributes
*copyc mmv$max_segment_length
*copyc osv$job_pageable_heap
*copyc i#move
*copyc pfi$convert_cycle_reference
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    chafa_information_request: [READ, oss$job_paged_literal] fst$goi_information_request :=
          [[fsc$specific_depth, 1], [fsc$goi_file_label, fsc$goi_job_environment_info, fsc$goi_cycle_info]];

  VAR
    fmv$null_cd_attachment_options: [XDCL, #GATE, READ, oss$job_paged_literal] fmt$cd_attachment_options :=
          [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0];

  VAR
    fmv$default_file_attributes: [oss$job_pageable, XDCL, #GATE] ^bat$static_label_attributes := NIL;

  VAR
    fmv$default_new_retention: [oss$job_pageable, XDCL, #GATE] ^fst$retention := NIL;

  VAR
    write_access: [STATIC, READ, oss$job_paged_literal] pft$usage_selections :=
          [pfc$append, pfc$modify, pfc$shorten],
    read_access: [STATIC, READ, oss$job_paged_literal] pft$usage_selections := [pfc$read],
    execute_access: [STATIC, READ, oss$job_paged_literal] pft$usage_selections := [pfc$execute],
    null_set: [STATIC, READ, oss$job_paged_literal] pft$usage_selections := [];

?? TITLE := '[XDCL] fmp$get_cd_info', EJECT ??

  PROCEDURE [XDCL, #GATE] fmp$get_cd_info
    (    evaluated_file_reference: fst$evaluated_file_reference;
         increment_open_count: boolean;
         lock_path_table: boolean;
     VAR open_cleanup_work_list: {i/o} fmt$open_cleanup_work_list;
     VAR system_file_attributes: bat$system_file_attributes;
     VAR global_file_information: bat$global_file_information;
     VAR attached_file: boolean;
     VAR file_previously_opened: boolean;
     VAR device_class: rmt$device_class;
     VAR cd_attachment_options: fmt$cd_attachment_options;
     VAR status: ost$status);

    VAR
      cycle_description: ^fmt$cycle_description,
      current_volume_number: amt$volume_number,
      current_vsns: rmt$volume_descriptor,
      density: rmt$density,
      eoi: amt$file_byte_address,
      file_label: ^SEQ ( * ),
      ignore_file_previously_opened: boolean,
      ignore_status: ost$status,
      label_type: amt$label_type,
      lock_status: ost$signature_lock_status,
      max_information_size: integer,
      number_of_volumes: amt$volume_number,
      object: ^fst$goi_object,
      object_information: ^SEQ ( * ),
      requested_volume_attributes: iot$requested_volume_attributes,
      setfa_label: bat$static_label_attributes,
      sfid: gft$system_file_identifier,
      validated_name: ost$name,
      volume_overflow_allowed: boolean,
      write_ring: rmt$write_ring;

?? NEWTITLE := 'merge_setfa_tape_attributes', EJECT ??

    PROCEDURE merge_setfa_tape_attributes
      (    setfa_label: bat$static_label_attributes;
       VAR static_label: {input, output} bat$static_label_attributes);

      IF setfa_label.block_type_source = amc$file_command THEN
        static_label.block_type := setfa_label.block_type;
        static_label.block_type_source := amc$file_command;
      ELSE
        static_label.block_type_source := amc$access_method_default;
      IFEND;
      IF setfa_label.character_conversion_source = amc$file_command THEN
        static_label.character_conversion := setfa_label.character_conversion;
        static_label.character_conversion_source := amc$file_command;
      ELSE
        static_label.character_conversion_source := amc$access_method_default;
      IFEND;
      IF setfa_label.internal_code_source = amc$file_command THEN
        static_label.internal_code := setfa_label.internal_code;
        static_label.internal_code_source := amc$file_command;
      ELSE
        static_label.internal_code_source := amc$access_method_default;
      IFEND;
      IF setfa_label.max_block_length_source = amc$file_command THEN
        static_label.max_block_length := setfa_label.max_block_length;
        static_label.max_block_length_source := amc$file_command;
      ELSE
        static_label.max_block_length_source := amc$access_method_default;
      IFEND;
      IF setfa_label.max_record_length_source = amc$file_command THEN
        static_label.max_record_length := setfa_label.max_record_length;
        static_label.max_record_length_source := amc$file_command;
      ELSE
        static_label.max_record_length_source := amc$access_method_default;
      IFEND;
      IF setfa_label.padding_character_source = amc$file_command THEN
        static_label.padding_character := setfa_label.padding_character;
        static_label.padding_character_source := amc$file_command;
      ELSE
        static_label.padding_character_source := amc$access_method_default;
      IFEND;
      IF setfa_label.record_type_source = amc$file_command THEN
        static_label.record_type := setfa_label.record_type;
        static_label.record_type_source := amc$file_command;
      ELSE
        static_label.record_type_source := amc$access_method_default;
      IFEND;

    PROCEND merge_setfa_tape_attributes;

?? TITLE := 'reset_tape_attribute_sources', EJECT ??

    PROCEDURE reset_tape_attribute_sources
      (VAR static_label: bat$static_label_attributes);

      static_label.block_type_source := amc$access_method_default;
      static_label.character_conversion_source := amc$access_method_default;
      static_label.internal_code_source := amc$access_method_default;
      static_label.max_block_length_source := amc$access_method_default;
      static_label.max_record_length_source := amc$access_method_default;
      static_label.padding_character_source := amc$access_method_default;
      static_label.record_type_source := amc$access_method_default;

    PROCEND reset_tape_attribute_sources;
?? OLDTITLE ??
?? EJECT ??

    attached_file := FALSE;
    file_previously_opened := FALSE;
    device_class := rmc$mass_storage_device;
    system_file_attributes.dynamic_label := fmv$system_file_attributes.dynamic_label;
    system_file_attributes.descriptive_label := fmv$system_file_attributes.descriptive_label;
    cd_attachment_options := fmv$null_cd_attachment_options;

    fmp$locate_cd_via_path_handle (evaluated_file_reference.path_handle_info.path_handle, lock_path_table,
          cycle_description, status);

    IF NOT status.normal THEN
      IF increment_open_count THEN
        osp$set_status_condition (fme$reattach_detached_file, status);
      ELSE
        IF fmv$default_file_attributes = NIL THEN
          system_file_attributes.static_label := fmv$system_file_attributes.static_label;
        ELSE
          system_file_attributes.static_label := fmv$default_file_attributes^;
        IFEND;
        global_file_information := fmv$global_file_information;
        status.normal := TRUE;
      IFEND;
      fmp$unlock_path_table;
      RETURN; {----->
    IFEND;

  /get_cd_info/
    BEGIN
      global_file_information := cycle_description^.global_file_information^;
      IF increment_open_count THEN
        osp$test_sig_lock (cycle_description^.global_file_information^.open_lock, lock_status);
        IF lock_status = osc$sls_locked_by_current_task THEN
          fsp$set_evaluated_file_abnormal (evaluated_file_reference, fse$open_already_in_progress,
                amc$open_req, '', status);
          EXIT /get_cd_info/; {----->
        ELSEIF lock_status = osc$sls_locked_by_another_task THEN
          osp$set_status_condition (fme$wait_for_open_lock, status);
          EXIT /get_cd_info/; {----->
        IFEND;
        osp$set_job_signature_lock (cycle_description^.global_file_information^.open_lock);
        osp$increment_locked_variable (cycle_description^.global_file_information^.open_count, 0,
              global_file_information.open_count);
        open_cleanup_work_list := open_cleanup_work_list + $fmt$open_cleanup_work_list
              [fmc$clear_open_lock, fmc$decrement_open_count];
        #SPOIL (open_cleanup_work_list);
      ELSE
        osp$fetch_locked_variable (cycle_description^.global_file_information^.open_count,
              global_file_information.open_count);
      IFEND;

      IF cycle_description^.cd_attachment_options <> NIL THEN
        cd_attachment_options := cycle_description^.cd_attachment_options^;
      IFEND;
      IF cycle_description^.attached_file THEN
        attached_file := TRUE;
        file_label := cycle_description^.system_file_label.static_label;
        file_previously_opened := cycle_description^.system_file_label.file_previously_opened;
        system_file_attributes.descriptive_label.application_info :=
              cycle_description^.system_file_label.descriptive_label.application_info;
        system_file_attributes.descriptive_label.global_access_mode :=
              cycle_description^.system_file_label.descriptive_label.global_access_mode;
        system_file_attributes.descriptive_label.global_file_name :=
              cycle_description^.system_file_label.descriptive_label.global_file_name;
        system_file_attributes.descriptive_label.global_share_mode :=
              cycle_description^.system_file_label.descriptive_label.global_share_mode;
        system_file_attributes.descriptive_label.internal_cycle_name :=
              cycle_description^.system_file_label.descriptive_label.internal_cycle_name;
        IF (cycle_description^.device_class = rmc$mass_storage_device) THEN
          system_file_attributes.descriptive_label.permanent_file := cycle_description^.permanent_file;
        IFEND;
        device_class := cycle_description^.device_class;
      ELSE
        file_label := NIL;
      IFEND;

      IF (cycle_description^.attached_file) AND ((cycle_description^.device_class =
            rmc$magnetic_tape_device) OR (cycle_description^.device_class = rmc$mass_storage_device)) AND
            (NOT global_file_information.eoi_set) THEN
        IF cycle_description^.device_class = rmc$magnetic_tape_device THEN
          global_file_information.eoi_byte_address := mmv$max_segment_length;
        ELSE
          dmp$fetch_eoi (cycle_description^.system_file_id, eoi, status);
          IF NOT status.normal THEN
            EXIT /get_cd_info/; {----->
          IFEND;
          global_file_information.eoi_byte_address := eoi;
        IFEND;
      IFEND;

      IF cycle_description^.dynamic_setfa_entries <> NIL THEN
        fmp$extract_dynamic_setfa_attrs (cycle_description^.dynamic_setfa_entries,
              system_file_attributes.dynamic_label);
      IFEND;

      IF cycle_description^.static_setfa_entries = NIL THEN
        fsp$expand_file_label (file_label, system_file_attributes.static_label, ignore_file_previously_opened,
              status);
        IF (device_class = rmc$magnetic_tape_device) AND file_previously_opened THEN
          reset_tape_attribute_sources (system_file_attributes.static_label);
        IFEND;

      ELSEIF file_label = NIL THEN
        IF (NOT file_previously_opened) OR (device_class = rmc$magnetic_tape_device) THEN
          fsp$expand_file_label (cycle_description^.static_setfa_entries, system_file_attributes.static_label,
                ignore_file_previously_opened, status);
        ELSE
          IF fmv$default_file_attributes = NIL THEN
            system_file_attributes.static_label := fmv$system_file_attributes.static_label;
          ELSE
            system_file_attributes.static_label := fmv$default_file_attributes^;
          IFEND;
        IFEND;

      ELSEIF (device_class = rmc$magnetic_tape_device) AND file_previously_opened THEN
        fsp$expand_file_label (cycle_description^.static_setfa_entries, setfa_label,
              ignore_file_previously_opened, status);
        IF NOT status.normal THEN
          EXIT /get_cd_info/; {----->
        IFEND;
        fsp$expand_file_label (file_label, system_file_attributes.static_label, ignore_file_previously_opened,
              status);
        IF NOT status.normal THEN
          EXIT /get_cd_info/; {----->
        IFEND;
        merge_setfa_tape_attributes (setfa_label, system_file_attributes.static_label);

      ELSE
        max_information_size := #SIZE (fst$goi_object_information) + #SIZE (fst$goi_object) +
              #SIZE (cycle_description^.static_setfa_entries^) + #SIZE (file_label^);
        PUSH object_information: [[REP max_information_size OF cell]];
        NEXT object IN object_information;
        IF object = NIL THEN
          osp$set_status_condition (pfe$info_full, status);
          EXIT /get_cd_info/; {----->
        IFEND;
        object^.object_type := fsc$goi_cycle_object;
        object^.file_label := file_label;
        fmp$merge_setfa_entries (cycle_description^.static_setfa_entries, object, object_information, status);
        IF NOT status.normal THEN
          EXIT /get_cd_info/; {----->
        IFEND;
        fsp$expand_file_label (object^.file_label, system_file_attributes.static_label,
              ignore_file_previously_opened, status);
      IFEND;

{ The following check will change the default max_block_length if the file is
{ a magnetic tape file on cartridge tape.  The check is here so an OPEN will store
{ the new default in the static label (via perserved_attributes).

      IF (cycle_description^.device_class = rmc$magnetic_tape_device) AND (NOT file_previously_opened) AND
            cycle_description^.attached_file THEN
        dmp$get_tape_volume_information (cycle_description^.system_file_id, number_of_volumes,
              current_volume_number, current_vsns, density, write_ring, requested_volume_attributes,
              volume_overflow_allowed, label_type, status);
        IF NOT status.normal THEN
          EXIT /get_cd_info/; {----->
        IFEND;
        fsp$adjust_tape_defaults (density, system_file_attributes.static_label);
      IFEND;

    END /get_cd_info/;

    fmp$unlock_path_table;

  PROCEND fmp$get_cd_info;
?? TITLE := '[XDCL] fmp$get_global_file_information', EJECT ??

  PROCEDURE [XDCL, #GATE] fmp$get_global_file_information
    (    evaluated_file_reference: fst$evaluated_file_reference;
     VAR global_file_information: bat$global_file_information;
     VAR status: ost$status);

    VAR
      cycle_description: ^fmt$cycle_description,
      local_evaluated_file_reference: fst$evaluated_file_reference;

    local_evaluated_file_reference := evaluated_file_reference;
    fmp$locate_cycle_description (local_evaluated_file_reference, cycle_description, status);

    IF status.normal THEN
      global_file_information := cycle_description^.global_file_information^;
      fmp$unlock_path_table;
    IFEND;

  PROCEND fmp$get_global_file_information;

?? TITLE := '[XDCL] fmp$change_default_file_attribs', EJECT ??

  PROCEDURE [XDCL, #GATE] fmp$change_default_file_attribs
    (    attributes: ^amt$file_attributes;
         new_retention: ^fst$retention;
         reset_system_defaults: boolean;
     VAR status: ost$status);


    VAR
      i: integer;

    IF reset_system_defaults THEN
      IF fmv$default_file_attributes <> NIL THEN
        FREE fmv$default_file_attributes IN osv$job_pageable_heap^;
      IFEND;
      IF fmv$default_new_retention <> NIL THEN
        FREE fmv$default_new_retention IN osv$job_pageable_heap^;
      IFEND;
    IFEND;

    IF new_retention <> NIL THEN
      IF fmv$default_new_retention = NIL THEN
        ALLOCATE fmv$default_new_retention IN osv$job_pageable_heap^;
      IFEND;
      fmv$default_new_retention^ := new_retention^;
    IFEND;

    IF attributes = NIL THEN
      RETURN; {----->
    IFEND;

    IF fmv$default_file_attributes = NIL THEN
      ALLOCATE fmv$default_file_attributes IN osv$job_pageable_heap^;
      fmv$default_file_attributes^ := fmv$system_file_attributes.static_label;
    IFEND;

    FOR i := LOWERBOUND (attributes^) TO UPPERBOUND (attributes^) DO
      CASE attributes^ [i].key OF
      = amc$lock_expiration_time =
        fmv$default_file_attributes^.lock_expiration_time := attributes^ [i].lock_expiration_time;
        fmv$default_file_attributes^.lock_expiration_time_source := amc$access_method_default;

      = amc$page_length =
        fmv$default_file_attributes^.page_length := attributes^ [i].page_length;
        fmv$default_file_attributes^.page_length_source := amc$access_method_default;

      = amc$page_width =
        fmv$default_file_attributes^.page_width := attributes^ [i].page_width;
        fmv$default_file_attributes^.page_width_source := amc$access_method_default;

      = amc$record_type =
        fmv$default_file_attributes^.record_type := attributes^ [i].record_type;
        fmv$default_file_attributes^.record_type_source := amc$access_method_default;
      CASEND;
    FOREND;

  PROCEND fmp$change_default_file_attribs;

?? TITLE := '[XDCL] fmp$change_file_attributes', EJECT ??

  PROCEDURE [XDCL, #GATE] fmp$change_file_attributes
    (    file_attributes: amt$file_attributes;
         evaluated_file_reference: fst$evaluated_file_reference;
         execution_ring: ost$valid_ring;
     VAR open_changed_file: boolean;
     VAR status: ost$status);

    VAR
      changed_file_label: ^SEQ ( * ),
      checksum_p: ^pft$checksum,
      combined_keyword_specified: boolean,
      converted_file_contents: amt$file_contents,
      cycle_description: ^fmt$cycle_description,
      cycle_selector: pft$cycle_selector,
      file_contents_specified: boolean,
      file_previously_opened: boolean,
      file_structure_specified: boolean,
      i: integer,
      information_request: fst$goi_information_request,
      job_routing_label: ^SEQ ( * ),
      label_header: ^fmt$static_label_header,
      local_open_changed_file: boolean,
      local_status: ost$status,
      local_system_file_label: fmt$system_file_label,
      object_information: ^fst$goi_object_information,
      object_info_sequence: ^SEQ ( * ),
      object_info_seq_size: ost$positive_integers,
      old_label_header: ^fmt$static_label_header,
      old_static_label_size: ost$non_negative_integers,
      open_count: integer,
      password_selector: pft$password_selector,
      path_string: fst$path,
      path_string_size: fst$path_size,
      pf_path: ^pft$path,
      physical_file_label_size: ost$non_negative_integers,
      seq_pointer: ^SEQ ( * ),
      specified_file_structure: amt$file_structure,
      split_file_contents: amt$file_contents,
      split_file_structure: amt$file_structure,
      start_of_label_p: ^SEQ ( * ),
      static_file_label: bat$static_label_attributes,
      static_label_size: ost$non_negative_integers,
      text: ost$name,
      warning_status: ost$status;

?? NEWTITLE := 'generate_changed_file_label', EJECT ??

    PROCEDURE [INLINE] generate_changed_file_label
      (VAR changed_file_label: ^SEQ ( * );
       VAR checksum_p: ^pft$checksum;
       VAR start_of_label_p: ^SEQ ( * ));

      ALLOCATE changed_file_label: [[REP physical_file_label_size OF cell]] IN osv$job_pageable_heap^;
      RESET changed_file_label;
      NEXT checksum_p IN changed_file_label;
      IF local_system_file_label.static_label = NIL THEN
        NEXT label_header IN changed_file_label;
        label_header^ := fmv$static_label_header;
        RESET changed_file_label TO label_header;
        NEXT start_of_label_p: [[REP static_label_size OF cell]] IN changed_file_label;
      ELSE
        NEXT start_of_label_p: [[REP static_label_size OF cell]] IN changed_file_label;
        i#move (local_system_file_label.static_label, start_of_label_p, static_label_size);
        FREE local_system_file_label.static_label IN osv$job_pageable_heap^;
      IFEND;

    PROCEND generate_changed_file_label;
?? OLDTITLE ??
?? EJECT ??

    open_changed_file := FALSE;
    status.normal := TRUE;
    warning_status.normal := TRUE;

    local_open_changed_file := FALSE;

    object_info_seq_size := #SIZE (fst$goi_object_information) + fsc$max_path_size + #SIZE (fst$goi_object) +
          #SIZE (fst$job_environment_information) + fmc$maximum_file_label_size;
    PUSH object_info_sequence: [[REP object_info_seq_size OF cell]];
    RESET object_info_sequence;

    information_request := chafa_information_request;
    pfp$r3_get_object_information (evaluated_file_reference, information_request, NIL, object_info_sequence,
          status);
    IF NOT status.normal THEN
      IF (status.condition = pfe$unknown_cycle) OR (status.condition = pfe$unknown_item) OR
            (status.condition = ame$file_not_known) THEN
        fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$file_not_known,
              amc$change_file_attributes_cmd, '', status);
      IFEND;
      RETURN; {----->
    IFEND;

    RESET object_info_sequence;
    NEXT object_information IN object_info_sequence;
    IF object_information = NIL THEN
      fsp$set_evaluated_file_abnormal (evaluated_file_reference, fme$system_error,
            amc$change_file_attributes_cmd, '- object information sequence is damaged', status);
      RETURN; {----->
    ELSEIF object_information^.object = NIL THEN
      fsp$set_evaluated_file_abnormal (evaluated_file_reference, fme$system_error,
            amc$change_file_attributes_cmd, '- object pointer is NIL', status);
      RETURN; {----->
    ELSEIF object_information^.object^.file_label = NIL THEN
      fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$not_old_file,
            amc$change_file_attributes_cmd, '', status);
      RETURN; {----->
    IFEND;

    fsp$expand_file_label (object_information^.object^.file_label, static_file_label, file_previously_opened,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF NOT file_previously_opened THEN
      fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$not_old_file,
            amc$change_file_attributes_cmd, '', status);
      RETURN; {----->
    IFEND;

    IF object_information^.object^.job_environment_information <> NIL THEN
      IF (object_information^.object^.job_environment_information^.cycle_attached) AND
            (object_information^.object^.job_environment_information^.attached_share_modes <>
            $fst$file_access_options []) THEN
        fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$improper_share_selection,
              amc$change_file_attributes_cmd, '', status);
        RETURN; {----->
      IFEND;
      IF object_information^.object^.job_environment_information^.concurrent_open_count <> 0 THEN
        fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$file_not_closed,
              amc$change_file_attributes_cmd, '', status);
        RETURN; {----->
      IFEND;
    IFEND;

    IF (object_information^.object^.cycle_information <> NIL) AND
          (object_information^.object^.cycle_information^.mainframe_usage_concurrency <>
          $fst$mainframe_usage_concurrency []) AND (object_information^.object^.job_environment_information =
          NIL) THEN { file is attached by another job }
      clp$convert_file_ref_to_string (evaluated_file_reference, {include_open_position} FALSE, path_string,
            path_string_size, local_status);
      osp$set_status_abnormal ('PF', pfe$cycle_busy, path_string (1, path_string_size), status);
      osp$append_status_integer (osc$status_parameter_delimiter, object_information^.object^.cycle_number, 10,
            FALSE, status);
      RETURN; {----->
    IFEND;

    IF (execution_ring > static_file_label.ring_attributes.r1) AND
          (avp$ring_min () > static_file_label.ring_attributes.r1) THEN
      fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$ring_validation_error,
            amc$change_file_attributes_cmd, '', status);
      RETURN; {----->
    IFEND;

    text := osc$null_name;
    FOR i := LOWERBOUND (file_attributes) TO UPPERBOUND (file_attributes) DO
      CASE file_attributes [i].key OF
      = amc$file_limit =
        IF file_attributes [i].file_limit <= static_file_label.file_limit THEN
          text := 'FILE LIMIT';
        IFEND;
      = amc$record_limit =
        IF file_attributes [i].record_limit <= static_file_label.record_limit THEN
          text := 'RECORD LIMIT';
        IFEND;
      ELSE
      CASEND;

      IF text <> osc$null_name THEN
        IF status.normal THEN
          fsp$set_evaluated_file_abnormal (evaluated_file_reference, ame$improper_new_attrib_value,
                amc$change_file_attributes_cmd, text, status);
        ELSE
          osp$append_status_parameter (',', text, status);
        IFEND;
        text := osc$null_name;
      IFEND;
    FOREND;
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    file_contents_specified := FALSE;
    file_structure_specified := FALSE;

    FOR i := LOWERBOUND (file_attributes) TO UPPERBOUND (file_attributes) DO
      CASE file_attributes [i].key OF
      = amc$file_contents =
        file_contents_specified := TRUE;
        fsp$convert_to_old_contents (file_attributes [i].file_contents, split_file_contents,
              split_file_structure);
        combined_keyword_specified := (split_file_structure <> fsc$unknown_contents) OR
              (split_file_contents = fsc$unknown_contents) OR (split_file_contents = fsc$source_map);
        static_file_label.file_contents_source := amc$change_file_attributes;

      = amc$file_limit =
        static_file_label.file_limit := file_attributes [i].file_limit;
        static_file_label.file_limit_source := amc$change_file_attributes;

      = amc$file_access_procedure =
        static_file_label.file_access_procedure := file_attributes [i].file_access_procedure;
        IF static_file_label.file_access_procedure = osc$null_name THEN
          static_file_label.file_access_procedure_source := amc$undefined_attribute;
        ELSE
          static_file_label.file_access_procedure_source := amc$change_file_attributes;
        IFEND;

      = amc$file_processor =
        static_file_label.file_processor := file_attributes [i].file_processor;
        static_file_label.file_processor_source := amc$change_file_attributes;

      = amc$file_structure =
        file_structure_specified := TRUE;
        specified_file_structure := file_attributes [i].file_structure;
        static_file_label.file_structure_source := amc$change_file_attributes;

      = amc$forced_write =
        static_file_label.forced_write := file_attributes [i].forced_write;
        static_file_label.forced_write_source := amc$change_file_attributes;

      = amc$line_number =
        static_file_label.line_number := file_attributes [i].line_number;
        static_file_label.line_number_source := amc$change_file_attributes;

      = amc$loading_factor =
        static_file_label.loading_factor := file_attributes [i].loading_factor;
        static_file_label.loading_factor_source := amc$change_file_attributes;

      = amc$lock_expiration_time =
        static_file_label.lock_expiration_time := file_attributes [i].lock_expiration_time;
        static_file_label.lock_expiration_time_source := amc$change_file_attributes;

      = amc$logging_options =
        static_file_label.logging_options := file_attributes [i].logging_options;
        static_file_label.logging_options_source := amc$change_file_attributes;
        local_open_changed_file := TRUE;

      = amc$log_residence =
        IF file_attributes [i].log_residence <> NIL THEN
          static_file_label.log_residence := file_attributes [i].log_residence^;
          IF static_file_label.log_residence = osc$null_name THEN
            static_file_label.log_residence_source := amc$undefined_attribute;
          ELSE
            static_file_label.log_residence_source := amc$change_file_attributes;
          IFEND;
          local_open_changed_file := TRUE;
        IFEND;

      = amc$ring_attributes =
        static_file_label.ring_attributes := file_attributes [i].ring_attributes;
        static_file_label.ring_attributes_source := amc$change_file_attributes;

      = amc$record_limit =
        static_file_label.record_limit := file_attributes [i].record_limit;
        static_file_label.record_limit_source := amc$change_file_attributes;

      = amc$statement_identifier =
        static_file_label.statement_identifier := file_attributes [i].statement_identifier;
        static_file_label.statement_identifier_source := amc$change_file_attributes;

      = amc$user_info =
        static_file_label.user_info := file_attributes [i].user_info;
        static_file_label.user_info_source := amc$change_file_attributes;

      ELSE
      CASEND;

    FOREND;

{ For reasons of compatibility, the specified keyword is split into the original file_contents and
{ file_structure components for storage in the file label; the single value of file_contents changes both
{ the file_contents and file_structure components in the label.  If an old value is specified for
{ file_contents (legible, list, object, screen) or file_structure (data, library, form, scl_include, etc.)
{ and the current values of file_contents and file_structure in the file_label represent one of the new
{ keywords, then the current values in the label are treated as a unit by the new value of file_contents
{ and/or file_structure; if the other parameter is not specified, the corresponding label field is set to
{ unknown.

    IF file_contents_specified THEN
      IF combined_keyword_specified OR NOT file_structure_specified THEN
        fsp$convert_file_contents (static_file_label.file_contents, static_file_label.file_structure,
              converted_file_contents, local_status);
        IF file_structure_specified OR NOT (((split_file_contents = fsc$unknown_contents) AND
              (split_file_structure = fsc$unknown_contents) AND
              (static_file_label.file_structure = fsc$data)) OR
              ((split_file_contents = fsc$list) AND (converted_file_contents = fsc$unknown_contents))) THEN
          IF combined_keyword_specified THEN
            IF file_structure_specified AND (specified_file_structure <> split_file_structure) THEN
              IF ((split_file_contents = fsc$list) AND (specified_file_structure = fsc$unknown_contents)) OR
                    ((split_file_contents = fsc$unknown_contents) AND (specified_file_structure = fsc$data))
                    THEN
                IF (NOT local_status.normal) AND (static_file_label.file_structure <>
                      specified_file_structure) THEN
                  bap$set_evaluated_file_abnormal (evaluated_file_reference, fse$file_structure_replaced, '',
                        static_file_label.file_structure, warning_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, specified_file_structure,
                        warning_status);
                IFEND;
                static_file_label.file_structure := specified_file_structure;
              ELSE
                bap$set_evaluated_file_abnormal (evaluated_file_reference, fse$file_structure_discarded, '',
                      specified_file_structure, warning_status);
                static_file_label.file_structure := split_file_structure;
              IFEND;
            ELSE
              IF (NOT local_status.normal) AND (static_file_label.file_structure <> split_file_structure) THEN
                bap$set_evaluated_file_abnormal (evaluated_file_reference, fse$file_structure_replaced, '',
                      static_file_label.file_structure, warning_status);
                osp$append_status_parameter (osc$status_parameter_delimiter, split_file_structure,
                      warning_status);
              IFEND;
              static_file_label.file_structure := split_file_structure;
            IFEND;
          ELSEIF local_status.normal THEN
            fsp$convert_file_contents (split_file_contents, static_file_label.file_structure,
                  converted_file_contents, local_status);
            IF NOT local_status.normal THEN
              static_file_label.file_structure := fsc$unknown_contents;
            IFEND;
          IFEND;
        IFEND;
      ELSEIF file_structure_specified THEN
        static_file_label.file_structure := specified_file_structure;
      IFEND;
      static_file_label.file_contents := split_file_contents;
    ELSEIF file_structure_specified THEN
      fsp$convert_file_contents (static_file_label.file_contents, specified_file_structure,
            converted_file_contents, local_status);
      IF NOT local_status.normal AND (static_file_label.file_contents <> fsc$unknown_contents) THEN
        fsp$convert_file_contents (static_file_label.file_contents, static_file_label.file_structure,
              converted_file_contents, local_status);
        IF local_status.normal THEN
          bap$set_evaluated_file_abnormal (evaluated_file_reference, fse$file_contents_replaced, '',
                converted_file_contents, warning_status);
          static_file_label.file_contents := fsc$unknown_contents;
        IFEND;
      IFEND;
      static_file_label.file_structure := specified_file_structure;
    IFEND;

{ Save label

    local_system_file_label.file_previously_opened := file_previously_opened;
    local_system_file_label.static_label := NIL;
    fmp$put_label_attributes (static_file_label, local_system_file_label);
    IF local_system_file_label.static_label = NIL THEN
      static_label_size := #SIZE (fmt$static_label_header);
    ELSE
      RESET local_system_file_label.static_label;
      static_label_size := #SIZE (local_system_file_label.static_label^);
      NEXT label_header IN local_system_file_label.static_label;
    IFEND;

    IF object_information^.object^.cycle_device_class = rmc$mass_storage_device THEN

{ Check for a job routing label in the old label.

      RESET object_information^.object^.file_label;
      NEXT old_label_header IN object_information^.object^.file_label;
      IF (old_label_header^.job_routing_label_size > 0) AND
            (fsp$path_element (^evaluated_file_reference, 1) ^ <> fsc$local) THEN

{ Append the job routing label of the old label to the new label.

        old_static_label_size := #SIZE (object_information^.object^.file_label^) -
              #SIZE (fmt$static_label_header) - old_label_header^.job_routing_label_size;
        IF old_static_label_size > 0 THEN
          NEXT seq_pointer: [[REP old_static_label_size OF cell]] IN object_information^.object^.file_label;
        IFEND;
        NEXT job_routing_label: [[REP old_label_header^.job_routing_label_size OF cell]] IN
              object_information^.object^.file_label;

        physical_file_label_size := #SIZE (pft$checksum) + static_label_size +
              old_label_header^.job_routing_label_size;
        generate_changed_file_label (changed_file_label, checksum_p, start_of_label_p);
        label_header^.job_routing_label_size := old_label_header^.job_routing_label_size;
        NEXT seq_pointer: [[REP label_header^.job_routing_label_size OF cell]] IN changed_file_label;
        seq_pointer^ := job_routing_label^;
      ELSE
        physical_file_label_size := #SIZE (pft$checksum) + static_label_size;
        generate_changed_file_label (changed_file_label, checksum_p, start_of_label_p);
      IFEND;
    ELSE
      label_header^.job_routing_label_size := 0;
      physical_file_label_size := #SIZE (pft$checksum) + static_label_size;
      generate_changed_file_label (changed_file_label, checksum_p, start_of_label_p);
    IFEND;

    pfp$compute_checksum (start_of_label_p, physical_file_label_size - #SIZE (pft$checksum), checksum_p^);

    IF fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local THEN
      fmp$locate_cd_via_path_handle (evaluated_file_reference.path_handle_info.path_handle,
            {lock_path_table} TRUE, cycle_description, status);
      IF NOT status.normal THEN
        FREE changed_file_label IN osv$job_pageable_heap^;
        RETURN; {----->
      IFEND;

      IF cycle_description^.system_file_label.static_label <> NIL THEN
        FREE cycle_description^.system_file_label.static_label IN osv$job_pageable_heap^;
      IFEND;
      cycle_description^.system_file_label.static_label := start_of_label_p;
      fmp$unlock_path_table;
    ELSE {permanent file}
      IF (object_information^.object^.job_environment_information <> NIL) AND
            object_information^.object^.job_environment_information^.cycle_attached THEN
        fmp$get_cycle_description (object_information^.resolved_path^, cycle_description, status);
        IF NOT status.normal THEN
          FREE changed_file_label IN osv$job_pageable_heap^;
          RETURN; {----->
        IFEND;

        pfp$save_file_label (cycle_description^.apfid, start_of_label_p, pfc$control, status);
        IF NOT status.normal THEN
          FREE changed_file_label IN osv$job_pageable_heap^;
          fmp$unlock_path_table;
          RETURN; {----->
        IFEND;

        IF cycle_description^.system_file_label.static_label <> NIL THEN
          FREE cycle_description^.system_file_label.static_label IN osv$job_pageable_heap^;
        IFEND;
        cycle_description^.system_file_label.static_label := start_of_label_p;
        fmp$unlock_path_table;
      ELSE { not attached }
        PUSH pf_path: [1 .. evaluated_file_reference.number_of_path_elements];
        pfp$convert_fs_to_pft$path (evaluated_file_reference, pf_path^);
        pfi$convert_cycle_reference (evaluated_file_reference.cycle_reference, cycle_selector, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
        password_selector.password_specified := pfc$default_password_option;
        pfp$r3_save_released_file_label (pf_path^, cycle_selector, TRUE {update_cycle_statistics} ,
              password_selector, changed_file_label, status);
        IF NOT status.normal THEN
          FREE changed_file_label IN osv$job_pageable_heap^;
          RETURN; {----->
        IFEND;
      IFEND;
    IFEND;

    open_changed_file := local_open_changed_file AND (static_file_label.file_organization IN
          amv$aam_file_organizations);

    IF status.normal AND NOT warning_status.normal THEN
      status := warning_status;
    IFEND;

  PROCEND fmp$change_file_attributes;

?? TITLE := '[XDCL] fmp$add_to_file_description' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] fmp$add_to_file_description
    (    file_identifier: amt$file_identifier;
         file_attributes: amt$add_to_attributes;
     VAR status: ost$status);

    TYPE
      fmt$attribute_set = set of amt$attribute_source;

    VAR
      attribute_validation_status: ost$status,
      bam_file_organizations: amt$file_organization_set,
      cl_path_handle: clt$path_handle,
      cycle_description: ^fmt$cycle_description,
      i: integer,
      i_string: ost$string,
      improper_attribute_key: boolean,
      file_instance: ^bat$task_file_entry,
      file_limit_specified: boolean,
      label_header: ^fmt$static_label_header,
      one: amt$collate_table,
      p_cell: ^cell,
      precedence_set: fmt$attribute_set,
      ptr1: ^string (50000),
      ptr2: ^string (50000),
      system_file_label: bat$static_label_attributes,
      text: ost$name,
      two: amt$collate_table;

    status.normal := TRUE;
    attribute_validation_status.normal := TRUE;
    improper_attribute_key := FALSE;
    file_limit_specified := TRUE;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_abnormal (amc$access_method_id, ame$improper_file_id, 'AMP$ADD_TO_FILE_DESCRIPTION',
            status);
      RETURN; {----->
    IFEND;

    clp$check_name_for_path_handle (file_instance^.local_file_name, cl_path_handle);

    fmp$locate_cd_via_path_handle (cl_path_handle.regular_handle, {lock_path_table} TRUE, cycle_description,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF NOT cycle_description^.attached_file THEN
      fmp$unlock_path_table;
      amp$set_file_instance_abnormal (file_identifier, ame$not_old_file, amc$add_to_file_description_req, '',
            status);
      RETURN; {----->
    IFEND;

    IF cycle_description^.system_file_label.file_previously_opened THEN
      fmp$unlock_path_table;
      amp$set_file_instance_abnormal (file_identifier, ame$not_open_new, amc$add_to_file_description_req, '',
            status);
      RETURN; {----->
    IFEND;

    fmp$get_label_attributes (^cycle_description^.system_file_label, system_file_label, status);

    bam_file_organizations := $amt$file_organization_set [amc$sequential, amc$byte_addressable];
    precedence_set := $fmt$attribute_set [amc$access_method_default, amc$undefined_attribute];
    text := osc$null_name;

    FOR i := 1 TO UPPERBOUND (file_attributes) DO
      CASE file_attributes [i].key OF

      = amc$character_conversion =

        IF (system_file_label.character_conversion_source IN precedence_set) THEN
          system_file_label.character_conversion := file_attributes [i].character_conversion;
          system_file_label.character_conversion_source := amc$add_to_file_description;
        ELSE
          text := 'CHARACTER_CONVERSION';
        IFEND;


      = amc$file_contents =

        IF (system_file_label.file_contents_source IN precedence_set) THEN
          system_file_label.file_contents := file_attributes [i].file_contents;
          system_file_label.file_contents_source := amc$add_to_file_description;
        ELSE
          text := 'FILE_CONTENTS';
        IFEND;

      = amc$file_limit =

        IF (system_file_label.file_limit_source IN precedence_set) THEN
          system_file_label.file_limit := file_attributes [i].file_limit;
          system_file_label.file_limit_source := amc$add_to_file_description;
          file_limit_specified := TRUE;
        ELSE
          text := 'FILE_LIMIT';
        IFEND;

      = amc$file_processor =

        IF (system_file_label.file_processor_source IN precedence_set) THEN
          system_file_label.file_processor := file_attributes [i].file_processor;
          system_file_label.file_processor_source := amc$add_to_file_description;
        ELSE
          text := 'FILE_PROCESSOR';
        IFEND;

      = amc$file_structure =

        IF (system_file_label.file_structure_source IN precedence_set) THEN
          system_file_label.file_structure := file_attributes [i].file_structure;
          system_file_label.file_structure_source := amc$add_to_file_description;
        ELSE
          text := 'FILE_STRUCTURE';
        IFEND;

      = amc$forced_write =

        IF (system_file_label.forced_write_source IN precedence_set) THEN
          system_file_label.forced_write := file_attributes [i].forced_write;
          system_file_label.forced_write_source := amc$add_to_file_description;
        ELSE
          text := 'FORCED_WRITE';
        IFEND;

      = amc$internal_code =

        IF (system_file_label.internal_code_source IN precedence_set) THEN
          system_file_label.internal_code := file_attributes [i].internal_code;
          system_file_label.internal_code_source := amc$add_to_file_description;
        ELSE
          text := 'INTERNAL_CODE';
        IFEND;

      = amc$line_number =

        IF (system_file_label.line_number_source IN precedence_set) THEN
          system_file_label.line_number := file_attributes [i].line_number;
          system_file_label.line_number_source := amc$add_to_file_description;
        ELSE
          text := 'LINE_NUMBER';
        IFEND;

      = amc$max_block_length =

        IF NOT (system_file_label.file_organization IN bam_file_organizations) THEN
          IF (system_file_label.max_block_length_source IN precedence_set) THEN
            system_file_label.max_block_length := file_attributes [i].max_block_length;
            system_file_label.max_block_length_source := amc$add_to_file_description;
          ELSE
            text := 'MAX_BLOCK_LENGTH';
          IFEND;
        ELSE
          improper_attribute_key := TRUE;
        IFEND;

      = amc$max_record_length =

        IF NOT (system_file_label.file_organization IN bam_file_organizations) THEN
          IF (system_file_label.max_record_length_source IN precedence_set) THEN
            system_file_label.max_record_length := file_attributes [i].max_record_length;
            system_file_label.max_record_length_source := amc$add_to_file_description;
          ELSE
            text := 'MAX_RECORD_LENGTH';
          IFEND;
        ELSE
          improper_attribute_key := TRUE;
        IFEND;

      = amc$min_block_length =

        IF (system_file_label.min_block_length_source IN precedence_set) THEN
          system_file_label.min_block_length := file_attributes [i].min_block_length;
          system_file_label.min_block_length_source := amc$add_to_file_description;
        ELSE
          text := 'MIN_BLOCK_LENGTH';
        IFEND;

      = amc$min_record_length =

        IF (system_file_label.min_record_length_source IN precedence_set) THEN
          system_file_label.min_record_length := file_attributes [i].min_record_length;
          system_file_label.min_record_length_source := amc$add_to_file_description;
        ELSE
          text := 'MIN_RECORD_LENGTH';
        IFEND;

      = amc$null_attribute =

        ;

      = amc$padding_character =

        IF (system_file_label.padding_character_source IN precedence_set) THEN
          system_file_label.padding_character := file_attributes [i].padding_character;
          system_file_label.padding_character_source := amc$add_to_file_description;
        ELSE
          text := 'PADDING_CHARACTER';
        IFEND;

      = amc$page_format =

        IF (system_file_label.page_format_source IN precedence_set) THEN
          system_file_label.page_format := file_attributes [i].page_format;
          system_file_label.page_format_source := amc$add_to_file_description;
        ELSE
          text := 'PAGE_FORMAT';
        IFEND;

      = amc$page_length =

        IF (system_file_label.page_length_source IN precedence_set) THEN
          system_file_label.page_length := file_attributes [i].page_length;
          system_file_label.page_length_source := amc$add_to_file_description;
        ELSE
          text := 'PAGE_LENGTH';
        IFEND;

      = amc$page_width =

        IF (system_file_label.page_width_source IN precedence_set) THEN
          system_file_label.page_width := file_attributes [i].page_width;
          system_file_label.page_width_source := amc$add_to_file_description;
        ELSE
          text := 'PAGE_WIDTH';
        IFEND;


      = amc$record_type =

        IF NOT (system_file_label.file_organization IN bam_file_organizations) THEN
          IF (system_file_label.record_type_source IN precedence_set) THEN
            system_file_label.record_type := file_attributes [i].record_type;
            system_file_label.record_type_source := amc$add_to_file_description;
          ELSE
            text := 'RECORD_TYPE';
          IFEND;
        ELSE
          improper_attribute_key := TRUE;
        IFEND;

      = amc$statement_identifier =

        IF (system_file_label.statement_identifier_source IN precedence_set) THEN
          system_file_label.statement_identifier := file_attributes [i].statement_identifier;
          system_file_label.statement_identifier_source := amc$add_to_file_description;
        ELSE
          text := 'STATEMENT_IDENTIFIER';
        IFEND;


      = amc$user_info =

        IF (system_file_label.user_info_source IN precedence_set) THEN
          system_file_label.user_info := file_attributes [i].user_info;
          system_file_label.user_info_source := amc$add_to_file_description;
        ELSE
          text := 'USER_INFO';
        IFEND;

      = amc$vertical_print_density =

        IF (system_file_label.vertical_print_density_source IN precedence_set) THEN
          system_file_label.vertical_print_density := file_attributes [i].vertical_print_density;
          system_file_label.vertical_print_density_source := amc$add_to_file_description;
        ELSE
          text := 'VERTICAL_PRINT_DENSITY';
        IFEND;


{ The following attributes are only used to describe files which
{ are accessed with the Advanced Access Method(AAM).  The
{ documentation of the AAM attributes are found in the AAM ERS.


      = amc$average_record_length =

        IF (system_file_label.average_record_length_source IN precedence_set) THEN
          system_file_label.average_record_length := file_attributes [i].average_record_length;
          system_file_label.average_record_length_source := amc$add_to_file_description;
        ELSE
          text := 'AVERAGE_RECORD_LENGTH';
        IFEND;

      = amc$collate_table =

        IF (file_attributes [i].collate_table = NIL) THEN
          clp$convert_integer_to_string (i, 10, FALSE, i_string, status);
          fmp$unlock_path_table;
          amp$set_file_instance_abnormal (file_identifier, ame$improper_file_attrib_value,
                amc$add_to_file_description_req, 'FILE_ATTRIBUTES', status);
          osp$append_status_parameter (osc$status_parameter_delimiter, i_string.value (1, i_string.size),
                status);
          RETURN; {----->
        IFEND;

        IF (system_file_label.collate_table_source IN precedence_set) THEN
          system_file_label.collate_table := file_attributes [i].collate_table^;
          system_file_label.collate_table_source := amc$add_to_file_description;
        ELSE
          one := system_file_label.collate_table;
          two := file_attributes [i].collate_table^;
          p_cell := ^one;
          ptr1 := p_cell;
          p_cell := ^two;
          ptr2 := p_cell;
          IF (ptr1^ (1, #SIZE (one)) <> ptr2^ (1, #SIZE (two))) THEN
            text := 'COLLATE_TABLE';
          IFEND;
        IFEND;

      = amc$data_padding =

        IF (system_file_label.data_padding_source IN precedence_set) THEN
          system_file_label.data_padding := file_attributes [i].data_padding;
          system_file_label.data_padding_source := amc$add_to_file_description;
        ELSE
          text := 'DATA_PADDING';
        IFEND;

      = amc$embedded_key =

        IF (system_file_label.embedded_key_source IN precedence_set) THEN
          system_file_label.embedded_key := file_attributes [i].embedded_key;
          system_file_label.embedded_key_source := amc$add_to_file_description;
        ELSE
          text := 'EMBEDDED_KEY';
        IFEND;

      = amc$estimated_record_count =

        IF (system_file_label.estimated_record_count_source IN precedence_set) THEN
          system_file_label.estimated_record_count := file_attributes [i].estimated_record_count;
          system_file_label.estimated_record_count_source := amc$add_to_file_description;
        ELSE
          text := 'ESTIMATED_RECORD_COUNT';
        IFEND;

      = amc$index_levels =

        IF (system_file_label.index_levels_source IN precedence_set) THEN
          system_file_label.index_levels := file_attributes [i].index_levels;
          system_file_label.index_levels_source := amc$add_to_file_description;
        ELSE
          text := 'INDEX_LEVELS';
        IFEND;

      = amc$index_padding =

        IF (system_file_label.index_padding_source IN precedence_set) THEN
          system_file_label.index_padding := file_attributes [i].index_padding;
          system_file_label.index_padding_source := amc$add_to_file_description;
        ELSE
          text := 'INDEX_PADDING';
        IFEND;

      = amc$key_length =

        IF (system_file_label.key_length_source IN precedence_set) THEN
          system_file_label.key_length := file_attributes [i].key_length;
          system_file_label.key_length_source := amc$add_to_file_description;
        ELSE
          text := 'KEY_LENGTH';
        IFEND;

      = amc$key_position =

        IF (system_file_label.key_position_source IN precedence_set) THEN
          system_file_label.key_position := file_attributes [i].key_position;
          system_file_label.key_position_source := amc$add_to_file_description;
        ELSE
          text := 'KEY_POSITION';
        IFEND;

      = amc$key_type =

        IF (system_file_label.key_type_source IN precedence_set) THEN
          system_file_label.key_type := file_attributes [i].key_type;
          system_file_label.key_type_source := amc$add_to_file_description;
        ELSE
          text := 'KEY_TYPE';
        IFEND;

      = amc$log_residence =

        IF (system_file_label.log_residence_source IN precedence_set) THEN
          IF file_attributes [i].log_residence <> NIL THEN
            system_file_label.log_residence := file_attributes [i].log_residence^;
            system_file_label.log_residence_source := amc$add_to_file_description;
          IFEND;
        ELSE
          text := 'LOG_RESIDENCE';
        IFEND;

      = amc$record_limit =

        IF (system_file_label.record_limit_source IN precedence_set) THEN
          system_file_label.record_limit := file_attributes [i].record_limit;
          system_file_label.record_limit_source := amc$add_to_file_description;
        ELSE
          text := 'RECORD_LIMIT';
        IFEND;

      = amc$records_per_block =

        IF (system_file_label.records_per_block_source IN precedence_set) THEN
          system_file_label.records_per_block := file_attributes [i].records_per_block;
          system_file_label.records_per_block_source := amc$add_to_file_description;
        ELSE
          text := 'RECORDS_PER_BLOCK';
        IFEND;

      ELSE
        improper_attribute_key := TRUE;
      CASEND;

      IF improper_attribute_key THEN
        clp$convert_integer_to_string (i, 10, FALSE, i_string, status);
        fmp$unlock_path_table;
        amp$set_file_instance_abnormal (file_identifier, ame$improper_file_attrib_key,
              amc$add_to_file_description_req, 'FILE_ATTRIBUTES', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, i_string.value (1, i_string.size),
              status);
        RETURN; {----->
      IFEND;

      IF text <> osc$null_name THEN
        IF attribute_validation_status.normal THEN
          fmp$unlock_path_table;
          amp$set_file_instance_abnormal (file_identifier, ame$attrib_already_defined,
                amc$add_to_file_description_req, text, attribute_validation_status);
        ELSE
          osp$append_status_parameter (',', text, attribute_validation_status);
        IFEND;
        text := osc$null_name;
      IFEND;
    FOREND;
    IF NOT attribute_validation_status.normal THEN
      status := attribute_validation_status;
      RETURN; {----->
    IFEND;

    IF file_limit_specified AND (cycle_description^.device_class = rmc$mass_storage_device) THEN
      dmp$set_file_limit (cycle_description^.system_file_id, system_file_label.file_limit, status);
      IF NOT status.normal THEN
        fmp$unlock_path_table;
        RETURN; {----->
      IFEND;
    IFEND;

    IF cycle_description^.system_file_label.static_label <> NIL THEN
      RESET cycle_description^.system_file_label.static_label;
      NEXT label_header IN cycle_description^.system_file_label.static_label;
      system_file_label.ring_attributes_source := label_header^.ring_attributes_source;
      system_file_label.ring_attributes := label_header^.ring_attributes;
      FREE cycle_description^.system_file_label.static_label IN osv$job_pageable_heap^;
    IFEND;

{   The call to fmp$put_label_attributes is preceded by setting
{ file_previously_opened to TRUE so that fmp$put_label_attributes will place
{ the ring_attributes in the static_label.  File_previously_opened is then set
{ back to FALSE, and is later set to TRUE in bap$end_new_open_processing when
{ the label is saved after the open has finished.
{   The fact that the static_label has a value of TRUE for
{ file_previously_opened is not a problem because all routines that check
{ file_previously_opened look at the value in the system_file_label.

    cycle_description^.system_file_label.file_previously_opened := TRUE;
    fmp$put_label_attributes (system_file_label, cycle_description^.system_file_label);
    cycle_description^.system_file_label.file_previously_opened := FALSE;
    IF (cycle_description^.system_file_label.static_label <> NIL) THEN
      RESET cycle_description^.system_file_label.static_label;
      NEXT label_header IN cycle_description^.system_file_label.static_label;
      IF cycle_description^.device_class = rmc$mass_storage_device THEN
        label_header^.job_routing_label_size := cycle_description^.job_routing_label_length;
      ELSE
        label_header^.job_routing_label_size := 0;
      IFEND;
    IFEND;

    fmp$unlock_path_table;

  PROCEND fmp$add_to_file_description;
*if false
?? TITLE := 'extract_dynamic_attributes', EJECT ??

  PROCEDURE extract_dynamic_attributes
    (    job_environment_information_p: ^fst$job_environment_information;
     VAR dynamic_label: {input/output} bat$dynamic_label_attributes);

    IF job_environment_information_p <> NIL THEN
      IF job_environment_information_p^.attachment_options_sources.access_modes_source = amc$file_command THEN
        #UNCHECKED_CONVERSION (job_environment_information_p^.setfa_access_modes, dynamic_label.access_mode);
      IFEND;

      IF job_environment_information_p^.attachment_options_sources.error_exit_name_source =
            amc$file_command THEN
        dynamic_label.error_exit_name := job_environment_information_p^.error_exit_procedure_name;
        dynamic_label.error_exit_name_source := amc$file_command;
      IFEND;

      IF job_environment_information_p^.attachment_options_sources.error_limit_source = amc$file_command THEN
        dynamic_label.error_limit := job_environment_information_p^.error_limit;
        dynamic_label.error_limit_source := amc$file_command;
      IFEND;

      IF job_environment_information_p^.attachment_options_sources.label_exit_name_source =
            amc$file_command THEN
        dynamic_label.label_exit_name := job_environment_information_p^.label_exit_procedure_name;
        dynamic_label.label_exit_name_source := amc$file_command;
      IFEND;

      IF job_environment_information_p^.attachment_options_sources.message_control_source =
            amc$file_command THEN
        dynamic_label.message_control := job_environment_information_p^.message_control;
        dynamic_label.message_control_source := amc$file_command;
      IFEND;

      IF job_environment_information_p^.attachment_options_sources.open_position_source =
            amc$file_command THEN
        dynamic_label.open_position := job_environment_information_p^.open_position;
        dynamic_label.open_position_source := amc$file_command;
      IFEND;
    IFEND;

  PROCEND extract_dynamic_attributes;
*ifend
MODEND fmm$file_attribute_manager;
