PROCEDURE (ram$repp) replace_procedure, replace_procedures, repp (
  procedure, procedures, p: list of any of
      integer radix 16
      name
      string
    anyend = all
  from, f: file = :$local.procedures
  to: file = $working_catalog.command_library
  status)

" PURPOSE:
"   Replace the specified modules on a library or object file.
" DESIGN:
"   Scan every module name on the library for the specified value. Merge the selected modules onto
"   the output file, and update the command list when appropriate.
" NOTES:
"   $WORKING_CATALOG.COMMAND_LIBRARY is overwritten if the catalog is :$LOCAL, otherwise cycle $NEXT
"   is created. An integer procedure value is hexadecimal value, convenient when processing CDCNET
"   configuration procedures. Chronological library order is maintained for audit purposes. A leading
"   or trailing blank constrains the substring match to the beginning or end of a module name.

  VAR
    command_list_altered : status
    format : name = library
    library_list : file = $unique(:$local)
    modules_on_file : list 0..$max_list of string = ()
    modules_to_replace : list 0..$max_list of string = ()
    next_cycle : file = to
    replace_status : status
    specified_name : string 1..31
  VAREND

  IF $file(to, permanent) THEN " create absolute path to cycle $next
    next_cycle=to//$file(to//$next, cycle_number)
  IFEND

  IF ($file(to, fs)= 'DATA') AND ($file(to, fc)= 'LEGIBLE') THEN
    format=scl_proc
  IFEND

  CREATE_OBJECT_LIBRARY
    add_modules library=to status=replace_status
    set_file_attributes file=library_list page_format=continuous file_contents=legible
    display_object_library library=from display_option=date_time output=library_list ..
          alphabetical_order=true status=replace_status
    IF replace_status.normal THEN
      PUSH file_connections " Suppress error messages from attempted update operations.
      delete_file_connection standard_file=$errors file=output
      delete_file_connection standard_file=$errors file=$job_log
      get_line variable=modules_on_file input=library_list
      delete_file file=library_list
      FOR EACH procedure_specified IN procedures DO " select a list of modules to replace
        IF $generic_type(procedure_specified)= integer THEN " a CDCNET configuration procedure reference
          specified_name=$integer_string(procedure_specified, 16)
        ELSE " a substring of the procedure name was specified
          specified_name=$string(procedure_specified)
        IFEND
        IF (specified_name = 'ALL') AND (format = scl_proc) THEN " select all SCL procedures
          modules_to_replace=$union(modules_to_replace, ..
                $select(modules_on_file, $scan_string('procedure', x)>0))
        ELSEIF specified_name = 'ALL' THEN " select all modules regardless of type
          modules_to_replace=$union(modules_to_replace, $select(modules_on_file, $size(x)>0))
        ELSEIF format = scl_proc THEN " select specified SCL procedures
          modules_to_replace=$union(modules_to_replace, $select(modules_on_file, ($scan_string('procedure', ..
                x)>0 AND $scan_string(specified_name, ' '//$substring(x, 1, 32))>0)))
        ELSE " select specified modules regardless of type
          modules_to_replace=$union(modules_to_replace, ..
                $select(modules_on_file, $scan_string(specified_name, ' '//$substring(x, 1, 32))>0))
        IFEND
      FOREND
      IF $nil(modules_to_replace) THEN " assign appropriate add_module status
        add_modules library=from modules=$apply(procedures, $range_of($program_name(x))) status=replace_status
        IF replace_status.normal THEN
          generate_library library=next_cycle format=format status=replace_status
        IFEND
      ELSE " generate the resulting library or object file
        put_line line=' Replacing procedures to     '//next_cycle output=$response
        FOR EACH selected_module IN modules_to_replace DO
          add_module library=from module=selected_module(1, 31) status=replace_status
          IF replace_status.normal THEN " account for the module added
            put_line line=' ADDED    '//$trim(selected_module(1, 31)) output=$response
          ELSE
            delete_module module=selected_module(1, 31) status=replace_status
            add_module library=from module=selected_module(1, 31) status=replace_status
            IF replace_status.normal THEN " account for the modules replaced
              put_line line=' REPLACED '//$trim(selected_module(1, 31)) output=$response
            IFEND
          IFEND
        FOREND
        delete_command_list_entry entry=to status=command_list_altered
        IF command_list_altered.normal THEN
          put_line line=' Deleted command list entry  '//to output=$response
        IFEND
        generate_library library=next_cycle format=format status=replace_status
        IF replace_status.normal THEN " summarize action performed
          put_line line=' Replaced '//$justify($integer_string($size(modules_to_replace)), 4, right)//..
' procedures to '//$string(next_cycle)//' from '//from output=$response
        IFEND
        IF command_list_altered.normal THEN " update the command list
          IF replace_status.normal THEN " add the new command library
            create_command_list_entry entry=next_cycle
            put_line line=' Created command list entry  '//next_cycle output=$response
          ELSE " restore the old command library
            create_command_list_entry entry=to
            put_line line=' Restored command list entry '//to output=$response
          IFEND
        IFEND
      IFEND
    IFEND
  QUIT

  EXIT_PROC WITH replace_status

PROCEND replace_procedure
