PROCEDURE rap$update_library(
  file, f: file = $required
  library, l: file = $required
  lock_out_library, lol: boolean = true
  status)


*IF $variable(rav$proc_doc,declared)<>'UNKNOWN'
"
"  This procedure combines modules from a file onto a library.  If the
"  lock out library parameter is true, the high and next cycles of the library
"  are locked to prevent any other attempt at writing a new cycle of this
"  library (this can happen when updating the di object library for CDCNET).
"
"  NOTE:  The library specified by the library parameter is assumed to not
"  have a cycle reference.
*IFEND


  VAR
    base_cycle: integer
    base_lfn: name = $name($unique)
    command_file: file = $local//$name($unique)
    delete_ring: integer
    ignore_status: status
    library_status: status
    local_status: status
    low_cycle: integer
    new_cycle: integer
    new_lfn: name = $name($unique)
    ring: array 1..3 of integer
    update_ring: integer

    rav$installation_environment: (XREF) rat$installation_environment
  VAREND


  update_block: ..
    BLOCK

  IF NOT $file(file permanent) THEN
    local_status = $status(FALSE, 'PF', pfe$unknown_permanent_file , $string(file))
    EXIT update_block WHEN NOT local_status.normal
  IFEND

  IF NOT $file(library permanent) THEN
    local_status = $status(FALSE, 'PF', pfe$unknown_permanent_file , $string(library))
    EXIT update_block WHEN NOT local_status.normal
  IFEND

  IF (($file(file file_content)<>'OBJECT') AND ($file(file file_structure)<>'LIBRARY')) THEN
    local_status = $status(FALSE, 'RA', rae$file_not_correct_format, $string(file), 'OBJECT LIBRARY')
    EXIT update_block WHEN NOT local_status.normal
  IFEND


*IF $variable(rav$proc_doc,declared)<>'UNKNOWN'

"  In the following discussion, 'R1' and 'R2' refer to the 1st and
"  2nd ring attributes respectively.
"
"  To perform the library update, task to R2 of the library
"  being updated when R2 is lower than the current execution ring.
"  Otherwise, stay at the current execution ring.  The library merge
"  cannot be performed on libraries whose R2 value is 3.  This is
"  because CREATE_OBJECT_LIBRARY cannot be called from ring 3.
"
"  To delete the previous cycle of the library, task to R1 of the library
"  whose cycle is being deleted when R1 is lower than the current
"  execution ring.  Otherwise, stay at the current execution ring.
*IFEND


  rap$get_file_ring_attributes fn=library r=ring status=local_status
  EXIT update_block WHEN NOT local_status.normal

  IF ring(1) < $ring THEN
    delete_ring = ring(1)
  ELSE
    delete_ring = $ring
  IFEND

  IF ring(2) < $ring THEN
    update_ring = ring(2)
  ELSE
    update_ring = $ring
  IFEND



  IF lock_out_library THEN


*IF $variable(rav$proc_doc,declared)<>'UNKNOWN'

"  The high cycle of the library is attached with share mode of none and
"  wait turned on.  This cycle of the library is then validated as an object
"  library.  The high cycle becomes the base source in CREOL.
"
"  The next cycle of the library is created using CREATE_FILE, this attaches
"  the next cycle until released by this procedure. The result of combining
"  the high cycle of the library and the file (from the file parameter) is
"  written to the next cycle (or new cycle as it is referred to in the code).
"
"  Once generation is complete and the ring attributes set on the new cycle, the
"  base and new cycles of the library are detached (releasing the lock).  The
"  base cycle is then deleted.
*IFEND


COLLECT_TEXT command_file until='END_LOCK_OUT_TEXT'
  TASK r=update_ring
    $system.attach_file f=library lfn=base_lfn sm=none wait=true
    base_cycle = $file(library cycle_number)

    IF (($file(library//base_cycle file_content) <> 'OBJECT') ..
          OR ($file(library//base_cycle file_structure) <> 'LIBRARY')) THEN
      library_status = $status(FALSE, 'RA', rae$file_not_correct_format, ..
            $string(library//base_cycle), 'OBJECT LIBRARY')
    ELSE

      $system.create_file f=library lfn=new_lfn
      new_cycle = $file(library cycle_number)

      $system.create_object_library
        add_module library//base_cycle
        combine_module file
        generate_library library//new_cycle
        quit
      $system.change_file_attributes library//new_cycle ra=(ring(1) ring(2) ring(3))
      $system.detach_file f=library//new_cycle status=ignore_status

      $system.detach_file f=library//base_cycle status=ignore_status
    IFEND
  TASKEND
  IF library_status.normal THEN
    IF NOT rav$installation_environment.save_previous_cycles THEN
      TASK r=delete_ring
        FOR low_cycle = 1 to ($size($file_cycles(library)) - 1) DO   "delete all cycles except 1."
          $system.delete_file f=library status=ignore_status
        FOREND
      TASKEND
    IFEND
  IFEND
END_LOCK_OUT_TEXT

  ELSE

*IF $variable(rav$proc_doc,declared)<>'UNKNOWN'

"  Do not lock out.
"
"  The library specifed on the parameter is validated as an object library.
"
"  The high cycle of the library and the file (from the file parameter) are combined
"  and the result is written to the $NEXT cycle of library.  Ring attributes are set
"  on the new cycle.
"  The $LOW cycle (assumed to be the old high cycle) of the library is then deleted.
"
"  NOTE:  The results cannot be guaranteed if other attempts are made to write to the
"  library at the same time without lockout.
*IFEND

  IF (($file(library file_content)<>'OBJECT') OR ($file(library file_structure)<>'LIBRARY')) THEN
    local_status = $status(FALSE, 'RA', rae$file_not_correct_format, $string(library), 'OBJECT LIBRARY')
    EXIT update_block WHEN NOT local_status.normal
  IFEND

COLLECT_TEXT command_file until='END_NO_LOCK_TEXT'
  TASK r=update_ring
    $system.create_object_library
      add_module library
      combine_module file
      generate_library library.$next
      quit
    $system.change_file_attributes library ra=(ring(1) ring(2) ring(3))
  TASKEND
  IF NOT rav$installation_environment.save_previous_cycles THEN
    TASK r=delete_ring
      FOR low_cycle = 1 to ($size($file_cycles(library)) - 1) DO   "delete all cycles except 1."
        $system.delete_file f=library status=ignore_status
      FOREND
    TASKEND
  IFEND
END_NO_LOCK_TEXT

  IFEND

  $system.include_file f=command_file status=local_status
  $system.delete_file f=command_file status=ignore_status
  EXIT update_block WHEN NOT local_status.normal

  BLOCKEND update_block

  EXIT procedure WITH local_status WHEN NOT local_status.normal
  EXIT procedure WITH library_status WHEN NOT library_status.normal

PROCEND rap$update_library
