?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Object Code Management : Binary Correction Generator' ??
MODULE ocm$apply_message_predictor;

{ PURPOSE:
{   This module updates offsets in a message module using a message module
{   "predictor" which contains offset change information that has been generated
{   from comparing two versions of the module.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc llt$library_member_header
*copyc llt$module_dictionary
*copyc llt$section_address
*copyc oct$name_index_changes
*copyc oct$offset_change_list
*copyc oct$single_module_predictor_hdr
*copyc ost$message_template
*copyc ost$mtm_condition_codes
*copyc ost$mtm_condition_names
*copyc ost$mtm_header
?? POP ??
*copyc ocp$new_global_offset
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$apply_message_predictor', EJECT ??
*copyc och$apply_message_predictor

  PROCEDURE [XDCL] ocp$apply_message_predictor
    (    p_module_predictor: ^SEQ ( * );
         module_dictionary: ^llt$module_dictionary;
         p_int_ol: ^SEQ ( * ));

    VAR
      member: record
        case boolean of
        = TRUE =
          pointer: ^SEQ ( * ),
        = FALSE =
          pva: ^cell,
        casend,
      recend,

      template: record
        case boolean of
        = TRUE =
          pointer: ^ost$message_template,
        = FALSE =
          pva: ^cell,
        casend,
      recend,

      condition_codes: ^ost$mtm_condition_codes,
      condition_names: ^ost$mtm_condition_names,
      found: boolean,
      i: llt$module_index,
      int_ol: ^SEQ ( * ),
      k: 0 .. osc$max_status_condition_code + 1,
      member_seq: ^SEQ ( * ),
      message_header: ^llt$library_member_header,
      message_module_ocv: ^oct$offset_change_list,
      message_name_index_changes: ^oct$name_index_changes,
      module_predictor: ^SEQ ( * ),
      module_predictor_header: ^oct$single_module_predictor_hdr,
      mtm_header: ^ost$mtm_header,
      new_offset: llt$section_address_range;

    int_ol := p_int_ol;
    module_predictor := p_module_predictor;

    RESET module_predictor;
    NEXT module_predictor_header IN module_predictor;
    NEXT message_name_index_changes: [0 .. module_predictor_header^.last_name_index] IN module_predictor;

    IF module_predictor_header^.length_message_template_cv > 0 THEN
      message_module_ocv := #PTR (module_predictor_header^.message_template_cv, module_predictor^);
    ELSE
      message_module_ocv := NIL;
    IFEND;

    found := FALSE;
    i := 1;
    WHILE NOT found AND (i <= UPPERBOUND (module_dictionary^)) DO
      found := ((module_dictionary^ [i].name = module_predictor_header^.module_name) AND
            ((module_dictionary^ [i].kind = llc$message_module) OR
            (module_dictionary^ [i].kind = llc$help_module)));
      IF found THEN
        message_header := #PTR (module_dictionary^ [i].message_header, int_ol^);
        member.pointer := #PTR (message_header^.member, int_ol^);
        RESET int_ol TO member.pointer;

        NEXT member_seq: [[REP message_header^.member_size OF cell]] IN int_ol;

        NEXT mtm_header IN member_seq;
        NEXT condition_codes: [0 .. mtm_header^.number_of_codes - 1] IN member_seq;
        FOR k := 0 TO UPPERBOUND (condition_codes^) DO
          IF message_name_index_changes^ [condition_codes^ [k].name_index] <>
                osc$max_status_condition_code THEN
            condition_codes^ [k].name_index := message_name_index_changes^ [condition_codes^ [k].name_index];
          IFEND;
        FOREND;

        NEXT condition_names: [0 .. mtm_header^.number_of_names - 1] IN member_seq;
        FOR k := 0 TO UPPERBOUND (condition_names^) DO
          template.pointer := #PTR (condition_names^ [k].template, member_seq^);
          new_offset := ocp$new_global_offset (#OFFSET (template.pointer), message_module_ocv);
          template.pva := #ADDRESS (#RING (template.pointer), #SEGMENT (template.pointer), new_offset);
?? PUSH (CHKRNG := OFF) ??
          condition_names^ [k].template := #REL (template.pointer, member_seq^);
?? POP ??
        FOREND;
        new_offset := ocp$new_global_offset (#OFFSET (member.pointer), message_module_ocv);
        member.pva := #ADDRESS (#RING (member.pointer), #SEGMENT (member.pointer), new_offset);
        message_header^.member := #REL (member.pointer, int_ol^);
      ELSE
        i := i + 1;
      IFEND;
    WHILEND;
  PROCEND ocp$apply_message_predictor;
?? OLDTITLE ??
MODEND ocm$apply_message_predictor;
