?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Clt$value Conversion Procedures' ??
MODULE clm$clt$value_conversion;

{
{ PURPOSE:
{   This module contains the procedures that convert between 'new' values
{   (clt$data_value, clt$internal_data_value) and 'old' values
{   (clt$value, clt$variable_value).

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clc$max_value_sets
*copyc clc$max_values_per_set
*copyc cle$bad_clt$value
*copyc cle$bad_clt$variable_value
*copyc cle$bad_data_value
*copyc cle$bad_internal_value
*copyc cle$not_supported
*copyc cle$string_too_long
*copyc cle$unexpected_value_type
*copyc cle$work_area_overflow
*copyc clt$data_value
*copyc clt$internal_data_value
*copyc clt$internal_data_value_header
*copyc clt$low_or_high
*copyc clt$type_conformance
*copyc clt$type_description
*copyc clt$value
*copyc clt$work_area
*copyc clv$type_kind_names
*copyc clv$value_descriptors
*copyc clv$value_type_kinds
*IF NOT $true(osv$unix)
*copyc cyd$run_time_error_condition
*IFEND
*copyc ost$status
?? POP ??
*copyc clp$append_status_value_type
*copyc clp$convert_to_clt$status
*copyc clp$convert_to_ost$status
*copyc clp$get_path_name
*copyc clp$get_work_area
*IF NOT $true(osv$unix)
*copyc clp$longreal_compare_le
*IFEND
*copyc clp$make_application_clt$value
*copyc clp$make_application_value
*copyc clp$make_array_value
*copyc clp$make_boolean_clt$value
*copyc clp$make_clt$boolean_value
*copyc clp$make_clt$integer_value
*copyc clp$make_clt$real_value
*copyc clp$make_clt$value
*copyc clp$make_file_clt$value
*IF NOT $true(osv$unix)
*copyc clp$make_file_value
*IFEND
*copyc clp$make_integer_clt$value
*copyc clp$make_name_clt$value
*copyc clp$make_name_value
*IF $true(osv$unix)
*copyc clp$make_nos_ve_file_value
*IFEND
*copyc clp$make_real_clt$value
*copyc clp$make_status_clt$value
*copyc clp$make_status_value
*copyc clp$make_string_value
*copyc clp$make_unspecified_value
*copyc clp$trimmed_string_size
*copyc i#current_sequence_position
*copyc osp$append_status_parameter
*IF NOT $true(osv$unix)
*copyc osp$establish_condition_handler
*IFEND
*copyc osp$set_status_abnormal
*IF NOT $true(osv$unix)
*copyc pmp$continue_to_cause
*IFEND
?? TITLE := 'clp$convert_clt$value_to_value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$convert_clt$value_to_value
    (    value: clt$value;
     VAR work_area {input, output} : ^clt$work_area;
     VAR data_value: ^clt$data_value;
     VAR status: ost$status);

*IF NOT $true(osv$unix)
?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
*IFEND
?? TITLE := 'bad_value', EJECT ??

    PROCEDURE bad_value;


      osp$set_status_abnormal ('CL', cle$bad_clt$value, '', status);
      EXIT clp$convert_clt$value_to_value;

    PROCEND bad_value;
?? TITLE := 'convert_application_value', EJECT ??

    PROCEDURE [INLINE] convert_application_value;

      VAR
        application_value: ^clt$application_value,
        text: ^clt$application_value_text;


      application_value := ^value.application;
      RESET application_value;
      NEXT text: [#SIZE (clt$application_value)] IN application_value;
      clp$make_application_value (text^, work_area, data_value);

    PROCEND convert_application_value;
?? TITLE := 'convert_boolean_value', EJECT ??

    PROCEDURE [INLINE] convert_boolean_value;


      clp$make_clt$boolean_value (value.bool, work_area, data_value);

    PROCEND convert_boolean_value;
?? TITLE := 'convert_file_value', EJECT ??

    PROCEDURE [INLINE] convert_file_value;

      VAR
        path: ^fst$path;


*IF NOT $true(osv$unix)
      PUSH path;
      clp$get_path_name (value.file.local_file_name, osc$full_message_level, path^);

      clp$make_file_value (path^ (1, clp$trimmed_string_size (path^)), work_area, data_value);
*ELSE
      clp$make_nos_ve_file_value (value.file.local_file_name, work_area, data_value);
*IFEND

    PROCEND convert_file_value;
?? TITLE := 'convert_integer_value', EJECT ??

    PROCEDURE [INLINE] convert_integer_value;


      clp$make_clt$integer_value (value.int, work_area, data_value);

    PROCEND convert_integer_value;
?? TITLE := 'convert_name_value', EJECT ??

    PROCEDURE [INLINE] convert_name_value;


      clp$make_name_value (value.name.value, work_area, data_value);

    PROCEND convert_name_value;
*IF NOT $true(osv$unix)
?? TITLE := 'convert_real_value', EJECT ??

    PROCEDURE [INLINE] convert_real_value;


      clp$make_clt$real_value (value.rnum, work_area, data_value);

    PROCEND convert_real_value;
*IFEND
?? TITLE := 'convert_status_value', EJECT ??

    PROCEDURE [INLINE] convert_status_value;


      clp$make_status_value (value.status, work_area, data_value);

    PROCEND convert_status_value;
?? TITLE := 'convert_string_value', EJECT ??

    PROCEDURE [INLINE] convert_string_value;


      clp$make_string_value (value.str.value (1, value.str.size), work_area, data_value);

    PROCEND convert_string_value;
?? TITLE := 'convert_unknown_value', EJECT ??

    PROCEDURE [INLINE] convert_unknown_value;


      clp$make_unspecified_value (work_area, data_value);

    PROCEND convert_unknown_value;
*IF NOT $true(osv$unix)
?? TITLE := 'convert_variable_reference', EJECT ??

    PROCEDURE [INLINE] convert_variable_reference;

      VAR
        lower_bound: clt$variable_dimension,
        upper_bound: clt$variable_dimension;

      CASE value.var_ref.value.kind OF
      = clc$boolean_value =
        lower_bound := LOWERBOUND (value.var_ref.value.boolean_value^);
        upper_bound := UPPERBOUND (value.var_ref.value.boolean_value^);
      = clc$integer_value =
        lower_bound := LOWERBOUND (value.var_ref.value.integer_value^);
        upper_bound := UPPERBOUND (value.var_ref.value.integer_value^);
      = clc$real_value =
        lower_bound := LOWERBOUND (value.var_ref.value.real_value^);
        upper_bound := UPPERBOUND (value.var_ref.value.real_value^);
      = clc$status_value =
        lower_bound := LOWERBOUND (value.var_ref.value.status_value^);
        upper_bound := UPPERBOUND (value.var_ref.value.status_value^);
      = clc$string_value =
        lower_bound := LOWERBOUND (value.var_ref.value.string_value^);
        upper_bound := (UPPERBOUND (value.var_ref.value.string_value^)) DIV
              (#SIZE (ost$string_size) + value.var_ref.value.max_string_size);
      ELSE
        bad_value;
      CASEND;

      clp$convert_var_value_to_value (value.var_ref.value, TRUE, lower_bound, upper_bound, work_area,
            data_value, status);

    PROCEND convert_variable_reference;
*IFEND
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    data_value := NIL;
*IF NOT $true(osv$unix)
    osp$establish_condition_handler (^abort_handler, FALSE);
*IFEND

    CASE value.kind OF
    = clc$application_value =
      convert_application_value;
    = clc$boolean_value =
      convert_boolean_value;
    = clc$file_value =
      convert_file_value;
    = clc$integer_value =
      convert_integer_value;
    = clc$name_value =
      convert_name_value;
*IF NOT $true(osv$unix)
    = clc$real_value =
      convert_real_value;
*IFEND
    = clc$status_value =
      convert_status_value;
    = clc$string_value =
      convert_string_value;
    = clc$unknown_value =
      convert_unknown_value;
*IF NOT $true(osv$unix)
    = clc$variable_reference =
      convert_variable_reference;
      IF NOT status.normal THEN
        RETURN;
      IFEND;
*IFEND
    ELSE
      bad_value;
    CASEND;

    IF data_value = NIL THEN
      osp$set_status_abnormal ('CL', cle$work_area_overflow, '', status);
    IFEND;

  PROCEND clp$convert_clt$value_to_value;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$convert_int_to_var_value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$convert_int_to_var_value
    (    internal_value: ^clt$internal_data_value;
         max_string_size: clt$string_size;
     VAR variable_value: clt$variable_value;
     VAR status: ost$status);

    VAR
      array_value: ^array [ * ] of REL (clt$internal_data_value) ^clt$i_data_value,
      element_index: clt$array_bound,
      first_element_kind: clt$data_kind,
      i_value: ^clt$i_data_value,
      local_max_string_size: ost$string_size,
      lower_bound: clt$array_bound,
      string_value_record: ^record
        size: ost$string_size,
        value: string ( * ),
      recend,
      string_value_seq: ^SEQ ( * ),
      upper_bound: clt$array_bound,
      variable_value_allocated: boolean,
      work_area: ^^clt$work_area;

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_internal_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_internal_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? TITLE := 'bad_internal_value', EJECT ??

    PROCEDURE bad_internal_value;


      osp$set_status_abnormal ('CL', cle$bad_internal_value, '', status);
      EXIT clp$convert_int_to_var_value;

    PROCEND bad_internal_value;
?? TITLE := 'bad_internal_value_type', EJECT ??

    PROCEDURE bad_internal_value_type;


      IF i_value^.kind = clc$deferred THEN
        osp$set_status_abnormal ('CL', cle$not_supported, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'DEFERRED value', status);
      ELSE
        osp$set_status_abnormal ('CL', cle$unexpected_value_type, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter,
              clv$type_kind_names [clv$value_type_kinds [i_value^.kind]], status);
      IFEND;
      EXIT clp$convert_int_to_var_value;

    PROCEND bad_internal_value_type;
?? TITLE := 'work_area_overflow', EJECT ??

    PROCEDURE work_area_overflow;


      osp$set_status_abnormal ('CL', cle$work_area_overflow, '', status);
      EXIT clp$convert_int_to_var_value;

    PROCEND work_area_overflow;
?? TITLE := 'allocate_variable_value', EJECT ??

    PROCEDURE [INLINE] allocate_variable_value;


      first_element_kind := i_value^.kind;
      CASE i_value^.kind OF
      = clc$boolean =
        variable_value.kind := clc$boolean_value;
        NEXT variable_value.boolean_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.boolean_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$integer =
        variable_value.kind := clc$integer_value;
        NEXT variable_value.integer_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.integer_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$real =
        variable_value.kind := clc$real_value;
        NEXT variable_value.real_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.real_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$status =
        variable_value.kind := clc$status_value;
        NEXT variable_value.status_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.status_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$string =
        variable_value.kind := clc$string_value;
        variable_value.max_string_size := local_max_string_size;
        NEXT variable_value.string_value: [1 .. ((upper_bound - lower_bound + 1) *
              (local_max_string_size + #SIZE (ost$string_size)))] IN work_area^;
        IF variable_value.string_value = NIL THEN
          work_area_overflow;
        IFEND;
        string_value_seq := #SEQ (variable_value.string_value^);
        RESET string_value_seq;
      = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
            clc$entry_point_reference, clc$keyword, clc$lock, clc$network_title, clc$program_name, clc$record,
            clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
            clc$time_increment, clc$time_zone, clc$type_specification =
        bad_internal_value_type;
      ELSE
        bad_internal_value;
      CASEND;
      variable_value.descriptor := clv$value_descriptors [variable_value.kind];

    PROCEND allocate_variable_value;
?? TITLE := 'create_variable_value', EJECT ??

    PROCEDURE [INLINE] create_variable_value;


      CASE i_value^.kind OF
      = clc$boolean =
        convert_boolean_value;
      = clc$integer =
        convert_integer_value;
      = clc$real =
        convert_real_value;
      = clc$status =
        convert_status_value;
      = clc$string =
        convert_string_value;
      = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
            clc$entry_point_reference, clc$keyword, clc$lock, clc$network_title, clc$program_name, clc$record,
            clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
            clc$time_increment, clc$time_zone, clc$type_specification =
        bad_internal_value_type;
      ELSE
        bad_internal_value;
      CASEND;

    PROCEND create_variable_value;
?? TITLE := 'convert_boolean_value', EJECT ??

    PROCEDURE [INLINE] convert_boolean_value;


      variable_value.boolean_value^ [element_index] := i_value^.boolean_value;

    PROCEND convert_boolean_value;
?? TITLE := 'convert_integer_value', EJECT ??

    PROCEDURE [INLINE] convert_integer_value;


      variable_value.integer_value^ [element_index] := i_value^.integer_value;

    PROCEND convert_integer_value;
?? TITLE := 'convert_real_value', EJECT ??

    PROCEDURE [INLINE] convert_real_value;


      variable_value.real_value^ [element_index] := i_value^.real_value;

    PROCEND convert_real_value;
?? TITLE := 'convert_status_value', EJECT ??

    PROCEDURE [INLINE] convert_status_value;

      VAR
        status_value: ^ost$status;


      status_value := #PTR (i_value^.status_value, internal_value^);

      clp$convert_to_clt$status (status_value^, variable_value.status_value^ [element_index]);

    PROCEND convert_status_value;
?? TITLE := 'convert_string_value', EJECT ??

    PROCEDURE [INLINE] convert_string_value;

      VAR
        string_length: ost$string_size,
        string_value: ^clt$string_value;


      string_value := #PTR (i_value^.string_value, internal_value^);

      IF STRLENGTH (string_value^) > local_max_string_size THEN
        string_length := local_max_string_size;
      ELSE
        string_length := STRLENGTH (string_value^);
      IFEND;
      NEXT string_value_record: [local_max_string_size] IN string_value_seq;
      string_value_record^.size := string_length;
      string_value_record^.value := string_value^ (1, string_length);

    PROCEND convert_string_value;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    variable_value_allocated := FALSE;
    IF max_string_size <= osc$max_string_size THEN
      local_max_string_size := max_string_size;
    ELSE
      local_max_string_size := osc$max_string_size;
    IFEND;

*IF NOT $true(osv$unix)
    clp$get_work_area (#RING (^work_area), work_area, status);
*ELSE
    clp$get_work_area (osc$user_ring, work_area, status);
*IFEND
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$establish_condition_handler (^abort_handler, FALSE);

    i_value := #PTR (internal_value^.header.value, internal_value^);

    IF i_value^.kind <> clc$array THEN
      lower_bound := 1;
      upper_bound := 1;
      element_index := 1;
      allocate_variable_value;
      create_variable_value;
      RETURN;
    IFEND;

    array_value := #PTR (i_value^.array_value, internal_value^);

    lower_bound := LOWERBOUND (array_value^);
    upper_bound := UPPERBOUND (array_value^);

    FOR element_index := 1 TO (upper_bound - lower_bound + 1) DO

      i_value := #PTR (array_value^ [element_index + lower_bound - 1], internal_value^);
      IF NOT variable_value_allocated THEN
        allocate_variable_value;
        variable_value_allocated := TRUE;
      ELSEIF i_value^.kind <> first_element_kind THEN
        bad_internal_value;
      IFEND;

      create_variable_value;

    FOREND;

  PROCEND clp$convert_int_to_var_value;
*IFEND
?? TITLE := 'clp$convert_value_to_clt$value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$convert_value_to_clt$value
    (    data_value: ^clt$data_value;
         value_set_number: 1 .. clc$max_value_sets;
         value_number: 1 .. clc$max_values_per_set;
         low_or_high: clt$low_or_high;
     VAR value: clt$value;
     VAR status: ost$status);

    VAR
      element_value: ^clt$data_value;

*IF NOT $true(osv$unix)
?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_data_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_data_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
*IFEND
?? TITLE := 'bad_data_value', EJECT ??

    PROCEDURE bad_data_value;


      osp$set_status_abnormal ('CL', cle$bad_data_value, '', status);
      EXIT clp$convert_value_to_clt$value;

    PROCEND bad_data_value;
?? TITLE := 'bad_data_value_type', EJECT ??

    PROCEDURE bad_data_value_type;


      IF element_value^.kind = clc$deferred THEN
        osp$set_status_abnormal ('CL', cle$not_supported, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'DEFERRED value', status);
      ELSE
        osp$set_status_abnormal ('CL', cle$unexpected_value_type, '', status);
        clp$append_status_value_type (osc$status_parameter_delimiter, element_value, status);
      IFEND;
      EXIT clp$convert_value_to_clt$value;

    PROCEND bad_data_value_type;
?? TITLE := 'convert_application_value', EJECT ??

    PROCEDURE [INLINE] convert_application_value;


      clp$make_application_clt$value (element_value^.application_value^, value);

    PROCEND convert_application_value;
?? TITLE := 'convert_boolean_value', EJECT ??

    PROCEDURE [INLINE] convert_boolean_value;


      clp$make_boolean_clt$value (element_value^.boolean_value, value);

    PROCEND convert_boolean_value;
?? TITLE := 'convert_file_value', EJECT ??

    PROCEDURE [INLINE] convert_file_value;

{     This assumes that the fst$file_reference really contains an amt$local_file_name.

      IF clp$trimmed_string_size (element_value^.file_value^) <= osc$max_name_size THEN
        clp$make_file_clt$value (element_value^.file_value^, value);
      ELSE
        bad_data_value;
      IFEND;

    PROCEND convert_file_value;
?? TITLE := 'convert_integer_value', EJECT ??

    PROCEDURE [INLINE] convert_integer_value;


      clp$make_integer_clt$value (element_value^.integer_value, value);

    PROCEND convert_integer_value;
?? TITLE := 'convert_keyword_value', EJECT ??

    PROCEDURE [INLINE] convert_keyword_value;


      clp$make_name_clt$value (element_value^.keyword_value,
            clp$trimmed_string_size (element_value^.data_name_value), value);

    PROCEND convert_keyword_value;
?? TITLE := 'convert_list_value', EJECT ??

    PROCEDURE [INLINE] convert_list_value;

      VAR
        current_node: ^clt$data_value,
        value_index: 0 .. clc$max_values_per_set,
        value_set_index: 0 .. clc$max_value_sets;


      current_node := element_value;
      element_value := NIL;
      value_set_index := 0;
      WHILE value_set_index < value_set_number DO
        IF current_node = NIL THEN
          clp$make_clt$value (clc$unknown_value, value);
          RETURN;
        IFEND;
        IF current_node^.kind <> clc$list THEN
          bad_data_value;
        IFEND;
        element_value := current_node^.element_value;
        IF element_value <> NIL THEN
          value_set_index := value_set_index + 1;
        IFEND;
        current_node := current_node^.link;
      WHILEND;

      IF element_value = NIL THEN
        clp$make_clt$value (clc$unknown_value, value);
        RETURN;
      ELSEIF element_value^.kind = clc$list THEN
        current_node := element_value;
        element_value := NIL;
        value_index := 0;
        WHILE value_index < value_number DO
          IF current_node = NIL THEN
            clp$make_clt$value (clc$unknown_value, value);
            RETURN;
          IFEND;
          IF current_node^.kind <> clc$list THEN
            bad_data_value;
          IFEND;
          element_value := current_node^.element_value;
          IF element_value <> NIL THEN
            value_index := value_index + 1;
          IFEND;
          current_node := current_node^.link;
        WHILEND;
      ELSEIF value_number <> 1 THEN
        clp$make_clt$value (clc$unknown_value, value);
        RETURN;
      IFEND;

      IF element_value = NIL THEN
        clp$make_clt$value (clc$unknown_value, value);
        RETURN;
      ELSEIF element_value^.kind = clc$range THEN
        IF low_or_high = clc$high THEN
          element_value := element_value^.high_value;
        ELSE
          element_value := element_value^.low_value;
        IFEND;
        IF element_value = NIL THEN
          clp$make_clt$value (clc$unknown_value, value);
          RETURN;
        IFEND;
      IFEND;

      convert_single_value;

    PROCEND convert_list_value;
?? TITLE := 'convert_name_value', EJECT ??

    PROCEDURE [INLINE] convert_name_value;


      clp$make_name_clt$value (element_value^.name_value, clp$trimmed_string_size
            (element_value^.data_name_value), value);

    PROCEND convert_name_value;
?? TITLE := 'convert_range_value', EJECT ??

    PROCEDURE [INLINE] convert_range_value;


      IF low_or_high = clc$high THEN
        element_value := element_value^.high_value;
      ELSE
        element_value := element_value^.low_value;
      IFEND;
      convert_single_value;

    PROCEND convert_range_value;
?? TITLE := 'convert_real_value', EJECT ??

    PROCEDURE [INLINE] convert_real_value;


      clp$make_real_clt$value (element_value^.real_value, value);

    PROCEND convert_real_value;
?? TITLE := 'convert_single_value', EJECT ??

    PROCEDURE [INLINE] convert_single_value;


      CASE element_value^.kind OF
      = clc$application =
        convert_application_value;
      = clc$boolean =
        convert_boolean_value;
*IF NOT $true(osv$unix)
      = clc$file =
*ELSE
      = clc$nos_ve_file =
*IFEND
        convert_file_value;
      = clc$integer =
        convert_integer_value;
      = clc$keyword =
        convert_keyword_value;
      = clc$name =
        convert_name_value;
      = clc$real =
        convert_real_value;
      = clc$status =
        convert_status_value;
      = clc$string =
        convert_string_value;
      = clc$unspecified =
        convert_unspecified_value;
      = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
            clc$entry_point_reference, clc$lock, clc$network_title, clc$program_name, clc$record,
            clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
*IF NOT $true(osv$unix)
            clc$time_increment, clc$time_zone, clc$type_specification =
*ELSE
            clc$time_increment, clc$time_zone, clc$type_specification, clc$unix_file =
*IFEND
        bad_data_value_type;
      ELSE
        bad_data_value;
      CASEND;

    PROCEND convert_single_value;
?? TITLE := 'convert_status_value', EJECT ??

    PROCEDURE [INLINE] convert_status_value;


      clp$make_status_clt$value (element_value^.status_value^, value);

    PROCEND convert_status_value;
?? TITLE := 'convert_string_value', EJECT ??

    PROCEDURE [INLINE] convert_string_value;

      VAR
        string_length: ost$string_size;


      IF STRLENGTH (element_value^.string_value^) > osc$max_string_size THEN
        string_length := osc$max_string_size;
      ELSE
        string_length := STRLENGTH (element_value^.string_value^);
      IFEND;
      clp$make_clt$value (clc$string_value, value);
      value.str.size := string_length;
      value.str.value := element_value^.string_value^ (1, string_length);

    PROCEND convert_string_value;
?? TITLE := 'convert_unspecified_value', EJECT ??

    PROCEDURE [INLINE] convert_unspecified_value;


      clp$make_clt$value (clc$unknown_value, value);

    PROCEND convert_unspecified_value;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    element_value := data_value;

    IF (element_value = NIL) OR ((element_value^.kind <> clc$list) AND
          ((value_set_number <> 1) OR (value_number <> 1))) THEN
      convert_unspecified_value;
      RETURN;
    IFEND;

*IF NOT $true(osv$unix)
    osp$establish_condition_handler (^abort_handler, FALSE);
*IFEND

    CASE element_value^.kind OF
    = clc$application =
      convert_application_value;
    = clc$boolean =
      convert_boolean_value;
*IF NOT $true(osv$unix)
    = clc$file =
*ELSE
    = clc$nos_ve_file =
*IFEND
      convert_file_value;
    = clc$integer =
      convert_integer_value;
    = clc$keyword =
      convert_keyword_value;
    = clc$list =
      convert_list_value;
    = clc$name =
      convert_name_value;
    = clc$range =
      convert_range_value;
    = clc$real =
      convert_real_value;
    = clc$status =
      convert_status_value;
    = clc$string =
      convert_string_value;
    = clc$unspecified =
      convert_unspecified_value;
    = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
          clc$entry_point_reference, clc$lock, clc$network_title, clc$program_name, clc$record,
          clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
*IF NOT $true(osv$unix)
          clc$time_increment, clc$time_zone, clc$type_specification =
*ELSE
          clc$time_increment, clc$time_zone, clc$type_specification, clc$unix_file =
*IFEND
      bad_data_value_type;
    ELSE
      bad_data_value;
    CASEND;

  PROCEND clp$convert_value_to_clt$value;
*IF NOT $true(osv$unix)
?? TITLE := 'clp$convert_value_to_var_value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$convert_value_to_var_value
    (    data_value: ^clt$data_value;
         max_string_size: clt$string_size;
     VAR variable_value: clt$variable_value;
     VAR status: ost$status);

    VAR
      element: ^clt$data_value,
      element_index: clt$array_bound,
      first_element_kind: clt$data_kind,
      local_max_string_size: ost$string_size,
      lower_bound: clt$array_bound,
      string_value_record: ^record
        size: ost$string_size,
        value: string ( * ),
      recend,
      string_value_seq: ^SEQ ( * ),
      upper_bound: clt$array_bound,
      variable_value_allocated: boolean,
      work_area: ^^clt$work_area;

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_data_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_data_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? TITLE := 'bad_data_value', EJECT ??

    PROCEDURE bad_data_value;


      osp$set_status_abnormal ('CL', cle$bad_data_value, '', status);
      EXIT clp$convert_value_to_var_value;

    PROCEND bad_data_value;
?? TITLE := 'bad_data_value_type', EJECT ??

    PROCEDURE bad_data_value_type;


      IF element^.kind = clc$deferred THEN
        osp$set_status_abnormal ('CL', cle$not_supported, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'DEFERRED value', status);
      ELSE
        osp$set_status_abnormal ('CL', cle$unexpected_value_type, '', status);
        clp$append_status_value_type (osc$status_parameter_delimiter, element, status);
      IFEND;
      EXIT clp$convert_value_to_var_value;

    PROCEND bad_data_value_type;
?? TITLE := 'work_area_overflow', EJECT ??

    PROCEDURE work_area_overflow;


      osp$set_status_abnormal ('CL', cle$work_area_overflow, '', status);
      EXIT clp$convert_value_to_var_value;

    PROCEND work_area_overflow;
?? TITLE := 'allocate_variable_value', EJECT ??

    PROCEDURE [INLINE] allocate_variable_value;


      first_element_kind := element^.kind;
      CASE element^.kind OF
      = clc$boolean =
        variable_value.kind := clc$boolean_value;
        NEXT variable_value.boolean_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.boolean_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$integer =
        variable_value.kind := clc$integer_value;
        NEXT variable_value.integer_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.integer_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$real =
        variable_value.kind := clc$real_value;
        NEXT variable_value.real_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.real_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$status =
        variable_value.kind := clc$status_value;
        NEXT variable_value.status_value: [1 .. (upper_bound - lower_bound + 1)] IN work_area^;
        IF variable_value.status_value = NIL THEN
          work_area_overflow;
        IFEND;
      = clc$string =
        variable_value.kind := clc$string_value;
        variable_value.max_string_size := local_max_string_size;
        NEXT variable_value.string_value: [1 .. ((upper_bound - lower_bound + 1) *
              (local_max_string_size + #SIZE (ost$string_size)))] IN work_area^;
        IF variable_value.string_value = NIL THEN
          work_area_overflow;
        IFEND;
        string_value_seq := #SEQ (variable_value.string_value^);
        RESET string_value_seq;
      = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
            clc$entry_point_reference, clc$keyword, clc$lock, clc$network_title, clc$program_name, clc$record,
            clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
            clc$time_increment, clc$time_zone, clc$type_specification =
        bad_data_value_type;
      ELSE
        bad_data_value;
      CASEND;
      variable_value.descriptor := clv$value_descriptors [variable_value.kind];

    PROCEND allocate_variable_value;
?? TITLE := 'create_variable_value', EJECT ??

    PROCEDURE [INLINE] create_variable_value;


      CASE element^.kind OF
      = clc$boolean =
        convert_boolean_value;
      = clc$integer =
        convert_integer_value;
      = clc$real =
        convert_real_value;
      = clc$status =
        convert_status_value;
      = clc$string =
        convert_string_value;
      = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
            clc$entry_point_reference, clc$keyword, clc$lock, clc$network_title, clc$program_name, clc$record,
            clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
            clc$time_increment, clc$time_zone, clc$type_specification =
        bad_data_value_type;
      ELSE
        bad_data_value;
      CASEND;

    PROCEND create_variable_value;
?? TITLE := 'convert_boolean_value', EJECT ??

    PROCEDURE [INLINE] convert_boolean_value;


      variable_value.boolean_value^ [element_index] := element^.boolean_value;

    PROCEND convert_boolean_value;
?? TITLE := 'convert_integer_value', EJECT ??

    PROCEDURE [INLINE] convert_integer_value;


      variable_value.integer_value^ [element_index] := element^.integer_value;

    PROCEND convert_integer_value;
?? TITLE := 'convert_real_value', EJECT ??

    PROCEDURE [INLINE] convert_real_value;


      variable_value.real_value^ [element_index] := element^.real_value;

    PROCEND convert_real_value;
?? TITLE := 'convert_status_value', EJECT ??

    PROCEDURE [INLINE] convert_status_value;


      clp$convert_to_clt$status (element^.status_value^, variable_value.status_value^ [element_index]);

    PROCEND convert_status_value;
?? TITLE := 'convert_string_value', EJECT ??

    PROCEDURE [INLINE] convert_string_value;

      VAR
        string_length: ost$string_size;


      IF STRLENGTH (element^.string_value^) > local_max_string_size THEN
        string_length := local_max_string_size;
      ELSE
        string_length := STRLENGTH (element^.string_value^);
      IFEND;
      NEXT string_value_record: [local_max_string_size] IN string_value_seq;
      string_value_record^.size := string_length;
      string_value_record^.value := element^.string_value^ (1, string_length);

    PROCEND convert_string_value;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    variable_value_allocated := FALSE;
    IF max_string_size <= osc$max_string_size THEN
      local_max_string_size := max_string_size;
    ELSE
      local_max_string_size := osc$max_string_size;
    IFEND;

*IF NOT $true(osv$unix)
    clp$get_work_area (#RING (^work_area), work_area, status);
*ELSE
    clp$get_work_area (osc$user_ring, work_area, status);
*IFEND
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osp$establish_condition_handler (^abort_handler, FALSE);

    IF data_value^.kind <> clc$array THEN
      lower_bound := 1;
      upper_bound := 1;
      element_index := 1;
      element := data_value;
      allocate_variable_value;
      create_variable_value;
      RETURN;
    IFEND;

    lower_bound := LOWERBOUND (data_value^.array_value^);
    upper_bound := UPPERBOUND (data_value^.array_value^);

    FOR element_index := 1 TO (upper_bound - lower_bound + 1) DO

      element := data_value^.array_value^ [element_index + lower_bound - 1];
      IF NOT variable_value_allocated THEN
        allocate_variable_value;
        variable_value_allocated := TRUE;
      ELSEIF element^.kind <> first_element_kind THEN
        bad_data_value;
      IFEND;

      create_variable_value;

    FOREND;

  PROCEND clp$convert_value_to_var_value;
?? TITLE := 'clp$convert_var_value_to_value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$convert_var_value_to_value
    (    variable_value: clt$variable_value;
         array_variable: boolean;
         lower_bound: clt$variable_dimension;
         upper_bound: clt$variable_dimension;
     VAR work_area {input, output} : ^clt$work_area;
     VAR data_value: ^clt$data_value;
     VAR status: ost$status);

    VAR
      osv$status_value: ost$status,
      p_string: ^ost$string,
      string_size: ost$string_size;

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? TITLE := 'bad_value', EJECT ??

    PROCEDURE bad_value;


      osp$set_status_abnormal ('CL', cle$bad_clt$variable_value, '', status);
      EXIT clp$convert_var_value_to_value;

    PROCEND bad_value;
?? TITLE := 'work_area_overflow', EJECT ??

    PROCEDURE work_area_overflow;


      osp$set_status_abnormal ('CL', cle$work_area_overflow, '', status);
      EXIT clp$convert_var_value_to_value;

    PROCEND work_area_overflow;
?? TITLE := 'convert_boolean_variable', EJECT ??

    PROCEDURE [INLINE] convert_boolean_variable;

      VAR
        i: clt$array_bound;


      IF (LOWERBOUND (variable_value.boolean_value^) <> 1) OR
            (UPPERBOUND (variable_value.boolean_value^) <> (upper_bound - lower_bound + 1)) THEN
        bad_value;
      IFEND;
      FOR i := lower_bound TO upper_bound DO
        clp$make_clt$boolean_value (variable_value.boolean_value^ [i - lower_bound + 1], work_area,
              data_value^.array_value^ [i]);
      FOREND;

    PROCEND convert_boolean_variable;
?? TITLE := 'convert_integer_variable', EJECT ??

    PROCEDURE [INLINE] convert_integer_variable;

      VAR
        i: clt$array_bound;


      IF (LOWERBOUND (variable_value.integer_value^) <> 1) OR
            (UPPERBOUND (variable_value.integer_value^) <> (upper_bound - lower_bound + 1)) THEN
        bad_value;
      IFEND;
      FOR i := lower_bound TO upper_bound DO
        clp$make_clt$integer_value (variable_value.integer_value^ [i - lower_bound + 1], work_area,
              data_value^.array_value^ [i]);
      FOREND;

    PROCEND convert_integer_variable;
?? TITLE := 'convert_real_variable', EJECT ??

    PROCEDURE [INLINE] convert_real_variable;

      VAR
        i: clt$array_bound;


      IF (LOWERBOUND (variable_value.real_value^) <> 1) OR
            (UPPERBOUND (variable_value.real_value^) <> (upper_bound - lower_bound + 1)) THEN
        bad_value;
      IFEND;
      FOR i := lower_bound TO upper_bound DO
        clp$make_clt$real_value (variable_value.real_value^ [i - lower_bound + 1], work_area,
              data_value^.array_value^ [i]);
      FOREND;

    PROCEND convert_real_variable;
?? TITLE := 'convert_status_variable', EJECT ??

    PROCEDURE [INLINE] convert_status_variable;

      VAR
        i: clt$array_bound,
        osv$status_value: ost$status;


      IF (LOWERBOUND (variable_value.status_value^) <> 1) OR
            (UPPERBOUND (variable_value.status_value^) <> (upper_bound - lower_bound + 1)) THEN
        bad_value;
      IFEND;
      FOR i := lower_bound TO upper_bound DO
        clp$convert_to_ost$status (variable_value.status_value^ [i - lower_bound + 1], osv$status_value);
        clp$make_status_value (osv$status_value, work_area, data_value^.array_value^ [i]);
      FOREND;

    PROCEND convert_status_variable;
?? TITLE := 'convert_string_variable', EJECT ??

    PROCEDURE [INLINE] convert_string_variable;

      VAR
        i: clt$array_bound,
        p_string: ^ost$string,
        string_element_size: integer,
        string_size: ost$string_size;


      string_element_size := #SIZE (ost$string_size) + variable_value.max_string_size;
      IF (LOWERBOUND (variable_value.string_value^) <> 1) OR
            (UPPERBOUND (variable_value.string_value^) <> ((upper_bound - lower_bound + 1) *
            string_element_size)) THEN
        bad_value;
      IFEND;
      FOR i := lower_bound TO upper_bound DO
        p_string := #LOC (variable_value.string_value^ [((i - lower_bound) * string_element_size) + 1]);
        IF p_string^.size <= variable_value.max_string_size THEN
          string_size := p_string^.size;
        ELSE
          string_size := 0;
        IFEND;
        clp$make_string_value (p_string^.value (1, string_size), work_area, data_value^.array_value^ [i]);
      FOREND;

    PROCEND convert_string_variable;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    IF array_variable THEN
      clp$make_array_value (lower_bound, upper_bound, work_area, data_value);
      IF data_value = NIL THEN
        work_area_overflow;
        RETURN;
      IFEND;

      CASE variable_value.kind OF
      = clc$boolean_value =
        convert_boolean_variable;
      = clc$integer_value =
        convert_integer_variable;
      = clc$real_value =
        convert_real_variable;
      = clc$status_value =
        convert_status_variable;
      = clc$string_value =
        convert_string_variable;
      ELSE
        bad_value;
      CASEND;
    ELSE
      CASE variable_value.kind OF
      = clc$boolean_value =
        IF (LOWERBOUND (variable_value.boolean_value^) = 1) AND
              (UPPERBOUND (variable_value.boolean_value^) = 1) THEN
          clp$make_clt$boolean_value (variable_value.boolean_value^ [1], work_area, data_value);
        ELSE
          bad_value;
        IFEND;
      = clc$integer_value =
        IF (LOWERBOUND (variable_value.integer_value^) = 1) AND
              (UPPERBOUND (variable_value.integer_value^) = 1) THEN
          clp$make_clt$integer_value (variable_value.integer_value^ [1], work_area, data_value);
        ELSE
          bad_value;
        IFEND;
      = clc$real_value =
        IF (LOWERBOUND (variable_value.real_value^) = 1) AND (UPPERBOUND (variable_value.real_value^) =
              1) THEN
          clp$make_clt$real_value (variable_value.real_value^ [1], work_area, data_value);
        ELSE
          bad_value;
        IFEND;
      = clc$status_value =
        IF (LOWERBOUND (variable_value.status_value^) = 1) AND (UPPERBOUND (variable_value.status_value^) =
              1) THEN
          clp$convert_to_ost$status (variable_value.status_value^ [1], osv$status_value);
          clp$make_status_value (osv$status_value, work_area, data_value);
        ELSE
          bad_value;
        IFEND;
      = clc$string_value =
        IF (LOWERBOUND (variable_value.string_value^) = 1) AND
              (UPPERBOUND (variable_value.string_value^) = (#SIZE (ost$string_size) +
              variable_value.max_string_size)) THEN
          p_string := #LOC (variable_value.string_value^ [1]);
          IF p_string^.size <= variable_value.max_string_size THEN
            string_size := p_string^.size;
          ELSE
            string_size := 0;
          IFEND;
          clp$make_string_value (p_string^.value (1, string_size), work_area, data_value);
        ELSE
          bad_value;
        IFEND;
      ELSE
        bad_value;
      CASEND;
    IFEND;

  PROCEND clp$convert_var_value_to_value;
?? TITLE := 'clp$get_single_data_value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$get_single_data_value
    (    value_set_number: 1 .. clc$max_value_sets;
         value_number: 1 .. clc$max_values_per_set;
         low_or_high: clt$low_or_high;
     VAR data_value {input, output} : ^clt$data_value;
     VAR status: ost$status);

    VAR
      element_value: ^clt$data_value;

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_data_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_data_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? TITLE := 'bad_data_value', EJECT ??

    PROCEDURE bad_data_value;


      osp$set_status_abnormal ('CL', cle$bad_data_value, '', status);
      EXIT clp$get_single_data_value;

    PROCEND bad_data_value;
?? TITLE := 'bad_data_value_type', EJECT ??

    PROCEDURE bad_data_value_type;


      IF element_value^.kind = clc$deferred THEN
        osp$set_status_abnormal ('CL', cle$not_supported, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'DEFERRED value', status);
      ELSE
        osp$set_status_abnormal ('CL', cle$unexpected_value_type, '', status);
        clp$append_status_value_type (osc$status_parameter_delimiter, element_value, status);
      IFEND;
      EXIT clp$get_single_data_value;

    PROCEND bad_data_value_type;
?? TITLE := 'interpret_list_value', EJECT ??

    PROCEDURE [INLINE] interpret_list_value;

      VAR
        current_node: ^clt$data_value,
        value_index: 0 .. clc$max_values_per_set,
        value_set_index: 0 .. clc$max_value_sets;


      current_node := element_value;
      element_value := NIL;
      value_set_index := 0;
      WHILE value_set_index < value_set_number DO
        IF current_node = NIL THEN
          RETURN;
        IFEND;
        IF current_node^.kind <> clc$list THEN
          bad_data_value;
        IFEND;
        element_value := current_node^.element_value;
        IF element_value <> NIL THEN
          value_set_index := value_set_index + 1;
        IFEND;
        current_node := current_node^.link;
      WHILEND;

      IF element_value = NIL THEN
        RETURN;
      ELSEIF element_value^.kind = clc$list THEN
        current_node := element_value;
        element_value := NIL;
        value_index := 0;
        WHILE value_index < value_number DO
          IF current_node = NIL THEN
            RETURN;
          IFEND;
          IF current_node^.kind <> clc$list THEN
            bad_data_value;
          IFEND;
          element_value := current_node^.element_value;
          IF element_value <> NIL THEN
            value_index := value_index + 1;
          IFEND;
          current_node := current_node^.link;
        WHILEND;
      ELSEIF value_number <> 1 THEN
        RETURN;
      IFEND;

      IF element_value = NIL THEN
        RETURN;
      ELSEIF element_value^.kind = clc$range THEN
        IF low_or_high = clc$high THEN
          element_value := element_value^.high_value;
        ELSE
          element_value := element_value^.low_value;
        IFEND;
        IF element_value = NIL THEN
          RETURN;
        IFEND;
      IFEND;
      data_value := element_value;

    PROCEND interpret_list_value;
?? TITLE := 'interpret_range_value', EJECT ??

    PROCEDURE [INLINE] interpret_range_value;


      IF low_or_high = clc$high THEN
        data_value := element_value^.high_value;
      ELSE
        data_value := element_value^.low_value;
      IFEND;

    PROCEND interpret_range_value;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    osp$establish_condition_handler (^abort_handler, FALSE);

    element_value := data_value;
    IF element_value = NIL THEN
      RETURN;
    IFEND;
    data_value := NIL;

    IF ((value_set_number <> 1) OR (value_number <> 1)) AND (element_value^.kind <> clc$list) THEN
      RETURN;
    IFEND;

    CASE element_value^.kind OF
*IF NOT $true(osv$unix)
    = clc$application, clc$boolean, clc$file, clc$integer, clc$keyword, clc$name, clc$real, clc$status,
*ELSE
    = clc$application, clc$boolean, clc$nos_ve_file, clc$integer, clc$keyword, clc$name, clc$real, clc$status,
*IFEND
          clc$string =
      IF (value_set_number = 1) AND (value_number = 1) THEN
        data_value := element_value;
      IFEND;
    = clc$list =
      interpret_list_value;
    = clc$range =
      IF (value_set_number = 1) AND (value_number = 1) THEN
        interpret_range_value;
      IFEND;
    = clc$unspecified =
      ;
    = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
          clc$entry_point_reference, clc$lock, clc$network_title, clc$program_name, clc$record,
          clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
*IF NOT $true(osv$unix)
          clc$time_increment, clc$time_zone, clc$type_specification =
*ELSE
          clc$time_increment, clc$time_zone, clc$type_specification, clc$unix_file =
*IFEND
      bad_data_value_type;
    ELSE
      bad_data_value;
    CASEND;

  PROCEND clp$get_single_data_value;
?? TITLE := 'clp$get_single_internal_value', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$get_single_internal_value
    (    internal_value: ^clt$internal_data_value;
         value_set_number: 1 .. clc$max_value_sets;
         value_number: 1 .. clc$max_values_per_set;
         low_or_high: clt$low_or_high;
     VAR internal_component {input, output} : REL (clt$internal_data_value) ^clt$i_data_value;
     VAR status: ost$status);

    VAR
      i_value: ^clt$i_data_value;

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);


      CASE condition.selector OF

      = pmc$system_conditions =
        IF (condition.system_conditions * $pmt$system_conditions
              [pmc$instruction_specification, pmc$address_specification, pmc$access_violation,
              pmc$invalid_segment_ring_0, pmc$divide_fault, pmc$arithmetic_overflow, pmc$exponent_overflow,
              pmc$exponent_underflow, pmc$fp_significance_loss, pmc$fp_indefinite,
              pmc$arithmetic_significance, pmc$invalid_bdp_data]) <> $pmt$system_conditions [] THEN
          bad_internal_value;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          bad_internal_value;
        IFEND;

      ELSE
        ;
      CASEND;

      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

    PROCEND abort_handler;
?? TITLE := 'bad_internal_value', EJECT ??

    PROCEDURE bad_internal_value;


      osp$set_status_abnormal ('CL', cle$bad_internal_value, '', status);
      EXIT clp$get_single_internal_value;

    PROCEND bad_internal_value;
?? TITLE := 'bad_internal_value_type', EJECT ??

    PROCEDURE bad_internal_value_type;


      IF i_value^.kind = clc$deferred THEN
        osp$set_status_abnormal ('CL', cle$not_supported, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'DEFERRED value', status);
      ELSE
        osp$set_status_abnormal ('CL', cle$unexpected_value_type, '', status);
        osp$append_status_parameter (osc$status_parameter_delimiter,
              clv$type_kind_names [clv$value_type_kinds [i_value^.kind]], status);
      IFEND;
      EXIT clp$get_single_internal_value;

    PROCEND bad_internal_value_type;
?? TITLE := 'interpret_list_value', EJECT ??

    PROCEDURE [INLINE] interpret_list_value;

      VAR
        current_node: ^clt$i_data_value,
        value_index: 0 .. clc$max_values_per_set,
        value_set_index: 0 .. clc$max_value_sets;


      current_node := i_value;
      i_value := NIL;
      value_set_index := 0;
      WHILE value_set_index < value_set_number DO
        IF current_node = NIL THEN
          RETURN;
        IFEND;
        IF current_node^.kind <> clc$list THEN
          bad_internal_value;
        IFEND;
        i_value := #PTR (current_node^.element_value, internal_value^);
        IF i_value <> NIL THEN
          value_set_index := value_set_index + 1;
        IFEND;
        current_node := #PTR (current_node^.link, internal_value^);
      WHILEND;

      IF i_value = NIL THEN
        RETURN;
      ELSEIF i_value^.kind = clc$list THEN
        current_node := i_value;
        i_value := NIL;
        value_index := 0;
        WHILE value_index < value_number DO
          IF current_node = NIL THEN
            RETURN;
          IFEND;
          IF current_node^.kind <> clc$list THEN
            bad_internal_value;
          IFEND;
          i_value := #PTR (current_node^.element_value, internal_value^);
          IF i_value <> NIL THEN
            value_index := value_index + 1;
          IFEND;
          current_node := #PTR (current_node^.link, internal_value^);
        WHILEND;
      ELSEIF value_number <> 1 THEN
        RETURN;
      IFEND;

      IF i_value = NIL THEN
        RETURN;
      ELSEIF i_value^.kind = clc$range THEN
        IF low_or_high = clc$high THEN
          i_value := #PTR (i_value^.high_value, internal_value^);
        ELSE
          i_value := #PTR (i_value^.low_value, internal_value^);
        IFEND;
        IF i_value = NIL THEN
          RETURN;
        IFEND;
      IFEND;
      internal_component := #REL (i_value, internal_value^);

    PROCEND interpret_list_value;
?? TITLE := 'interpret_range_value', EJECT ??

    PROCEDURE [INLINE] interpret_range_value;


      IF low_or_high = clc$high THEN
        internal_component := i_value^.high_value;
      ELSE
        internal_component := i_value^.low_value;
      IFEND;

    PROCEND interpret_range_value;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    osp$establish_condition_handler (^abort_handler, FALSE);

    i_value := #PTR (internal_component, internal_value^);

    IF ((value_set_number <> 1) OR (value_number <> 1)) AND (i_value^.kind <> clc$list) THEN
      RETURN;
    IFEND;

    CASE i_value^.kind OF
*IF NOT $true(osv$unix)
    = clc$application, clc$boolean, clc$file, clc$integer, clc$keyword, clc$name, clc$real, clc$status,
*ELSE
    = clc$application, clc$boolean, clc$nos_ve_file, clc$integer, clc$keyword, clc$name, clc$real, clc$status,
*IFEND
          clc$string =
      IF (value_set_number = 1) AND (value_number = 1) THEN
        internal_component := #REL (i_value, internal_value^);
      IFEND;
    = clc$list =
      interpret_list_value;
    = clc$range =
      IF (value_set_number = 1) AND (value_number = 1) THEN
        interpret_range_value;
      IFEND;
    = clc$unspecified =
      ;
    = clc$array, clc$cobol_name, clc$command_reference, clc$data_name, clc$date_time, clc$deferred,
          clc$entry_point_reference, clc$lock, clc$network_title, clc$program_name, clc$record,
          clc$scu_line_identifier, clc$statistic_code, clc$status_code, clc$string_pattern,
*IF NOT $true(osv$unix)
          clc$time_increment, clc$time_zone, clc$type_specification =
*ELSE
          clc$time_increment, clc$time_zone, clc$type_specification, clc$unix_file =
*IFEND
      bad_internal_value_type;
    ELSE
      bad_internal_value;
    CASEND;

  PROCEND clp$get_single_internal_value;
*IFEND

MODEND clm$clt$value_conversion;
