
?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Screen Formatting: Process Table' ??
MODULE fdm$process_table;

{ PURPOSE:
{   This module creates, changes, gets data about a form table definition.
{
{ DESIGN:
{   Do not make any changes to a form table definitions if any of the changes
{   are not valid.
{
{ NOTES:
{   All external procedures appear first in alphabetical order.  Then all
{   procedures used by this module.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??

?? PUSH (LISTEXT := ON) ??
*copyc cyd$run_time_error_condition
*copyc fdc$system_occurrence
*copyc fde$condition_identifiers
*copyc fdt$form_definition
*copyc fdt$form_identifier
*copyc fdt$form_module
*copyc fdt$form_object_definition
*copyc fdt$form_status
*copyc fdt$form_table_definition
*copyc fdt$form_variable_definition
*copyc fdt$get_table_attributes
*copyc fdt$number_table_variables
*copyc fdt$number_tables
*copyc fdt$table_attribute_index
*copyc fdt$table_attributes
*copyc fdt$table_index
*copyc fdt$table_variable_index
*copyc fdt$table_variable
*copyc fdt$table_variables
*copyc fdt$variable_index
*copyc ost$name
?? POP ??

*copyc fdp$find_change_form_definition
*copyc fdp$find_form_definition
*copyc fdp$find_table_definition
*copyc fdp$find_variable_definition
*copyc fdp$ptr_table_variables
*copyc fdp$rel_table_objects
*copyc fdp$rel_table_variables
*copyc fdp$rel_tables
*copyc fdp$validate_name
*copyc pmp$continue_to_cause
*copyc osp$append_status_parameter
*copyc osp$append_status_integer
*copyc osp$disestablish_cond_handler
*copyc osp$establish_condition_handler
*copyc osp$set_status_abnormal

?? TITLE := 'Global Declarations Declared by This Module', EJECT ??

  CONST
    fdc$tables_to_expand = 2,
    fdc$table_variables_to_expand = 4;

?? TITLE := 'fdp$change_table', EJECT ??
*copyc fdh$change_table

  PROCEDURE [XDCL] fdp$change_table
    (    form_identifier: fdt$form_identifier;
         table_name: ost$name;
     VAR table_attributes: fdt$table_attributes;
     VAR status: ost$status);

    VAR
      name_exists: boolean,
      name_is_valid: boolean,
      form_table_definition: fdt$form_table_definition,
      p_form_definition: ^fdt$form_definition,
      p_form_status: ^fdt$form_status,
      p_form_table_definition: ^fdt$form_table_definition,
      table_index: fdt$table_index,
      valid_name: ost$name;

?? NEWTITLE := 'condition_handler', EJECT ??

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           stack_frame_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
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$change_table;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$change_table;
        IFEND;

      ELSE
        ;
      CASEND;
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
    PROCEND condition_handler;

?? OLDTITLE, EJECT ??

    osp$establish_condition_handler (^condition_handler, FALSE);
    FOR table_index := LOWERBOUND (table_attributes) TO UPPERBOUND (table_attributes) DO
      table_attributes [table_index].put_value_status := fdc$unprocessed_put_value;
    FOREND;

    fdp$find_change_form_definition (form_identifier, p_form_status, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    p_form_definition := p_form_status^.p_form_definition;
    fdp$validate_name (table_name, p_form_definition^.processor, valid_name, name_is_valid);
    IF NOT name_is_valid THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

    fdp$find_table_definition (valid_name, p_form_status^.p_form_table_definitions,
          p_form_definition^.form_table_definitions.active_number, p_form_table_definition, table_index,
          name_exists);
    IF NOT name_exists THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$unknown_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

{ Work on copy of table definition so that no bad changes occur to stored table definition.

    form_table_definition := p_form_table_definition^;
    change_table (p_form_status, ^form_table_definition, table_attributes, status);

{ If all changes are good, then update stored table definition.

    IF status.normal THEN
      p_form_table_definition^ := form_table_definition;
    IFEND;

  PROCEND fdp$change_table;

?? TITLE := 'fdp$create_table', EJECT ??
*copyc fdh$create_table

  PROCEDURE [XDCL] fdp$create_table
    (    form_identifier: fdt$form_identifier;
         table_name: ost$name;
     VAR table_attributes: fdt$table_attributes;
     VAR status: ost$status);

    VAR
      form_table_definition: fdt$form_table_definition,
      name_exists: boolean,
      name_is_valid: boolean,
      p_form_definition: ^fdt$form_definition,
      p_form_status: ^fdt$form_status,
      p_form_object_definition: ^fdt$form_object_definition,
      p_form_table_definition: ^fdt$form_table_definition,
      p_form_variable_definition: ^fdt$form_variable_definition,
      table_index: fdt$table_index,
      valid_name: ost$name,
      variable_index: fdt$variable_index;

?? NEWTITLE := 'allocate_table', EJECT ??

    PROCEDURE [INLINE] allocate_table
      (VAR p_form_table_definition: ^fdt$form_table_definition);

      VAR
        i: fdt$table_index,
        number_tables: fdt$number_tables,
        p_new_table_definitions: ^array [1 .. * ] of fdt$form_table_definition,
        p_old_table_definitions: ^array [1 .. * ] of fdt$form_table_definition;

      p_old_table_definitions := p_form_status^.p_form_table_definitions;
      IF p_old_table_definitions = NIL THEN
        NEXT p_new_table_definitions: [1 .. fdc$tables_to_expand] IN p_form_status^.p_form_module;
        IF p_new_table_definitions = NIL THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$no_space_available, '', status);
          RETURN;
        IFEND;

        fdp$rel_tables (p_new_table_definitions, p_form_status);
        p_form_table_definition := ^p_new_table_definitions^ [1];
        p_form_definition^.form_table_definitions.active_number := 1;
        RETURN;
      IFEND;

{ An array for tables exists. Try to find an inactive entry.
{ Minimize number of allocations for table space.

      number_tables := p_form_definition^.form_table_definitions.active_number;
      IF number_tables < p_form_definition^.form_table_definitions.total_number THEN
        number_tables := number_tables + 1;
        p_form_definition^.form_table_definitions.active_number := number_tables;
        p_form_table_definition := ^p_old_table_definitions^ [number_tables];
        RETURN;
      IFEND;

{ Expand the array for tables.

      NEXT p_new_table_definitions: [1 .. fdc$tables_to_expand + number_tables] IN
            p_form_status^.p_form_module;
      IF p_new_table_definitions = NIL THEN
        osp$set_status_abnormal (fdc$format_display_identifier, fde$no_space_available, '', status);
        RETURN;
      IFEND;

{ Copy old tables to new array.

      FOR i := 1 TO number_tables DO
        p_new_table_definitions^ [i] := p_old_table_definitions^ [i];
      FOREND;

      fdp$rel_tables (p_new_table_definitions, p_form_status);
      number_tables := number_tables + 1;
      p_form_definition^.form_table_definitions.active_number := number_tables;
      p_form_table_definition := ^p_new_table_definitions^ [number_tables];
    PROCEND allocate_table;

?? OLDTITLE ??
?? NEWTITLE := 'condition_handler', EJECT ??

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           stack_frame_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
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$create_table;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$create_table;
        IFEND;

      ELSE
        ;
      CASEND;
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
    PROCEND condition_handler;

?? OLDTITLE, EJECT ??

    osp$establish_condition_handler (^condition_handler, FALSE);
    FOR table_index := LOWERBOUND (table_attributes) TO UPPERBOUND (table_attributes) DO
      table_attributes [table_index].put_value_status := fdc$unprocessed_put_value;
    FOREND;

    fdp$find_change_form_definition (form_identifier, p_form_status, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    p_form_definition := p_form_status^.p_form_definition;
    fdp$validate_name (table_name, p_form_definition^.processor, valid_name, name_is_valid);
    IF NOT name_is_valid THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

{ The new table name must not currently exist as a table name or a variable name.

    fdp$find_table_definition (valid_name, p_form_status^.p_form_table_definitions,
          p_form_definition^.form_table_definitions.active_number, p_form_table_definition, table_index,
          name_exists);
    IF name_exists THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$table_name_exists, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

    fdp$find_variable_definition (valid_name, p_form_status^.p_form_variable_definitions,
          p_form_definition^.form_variable_definitions.active_number, p_form_variable_definition,
          variable_index, name_exists);
    IF name_exists THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$table_name_exists, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

{ Set table definition default values.

    form_table_definition.access_all_occurrences := FALSE;
    form_table_definition.name := valid_name;
    form_table_definition.stored_occurrence := fdc$system_occurrence;
    form_table_definition.table_variables.total_number := 0;
    form_table_definition.table_variables.active_number := 0;
    form_table_definition.valid := FALSE;
    form_table_definition.visible_occurrence_defined := FALSE;
    change_table (p_form_status, ^form_table_definition, table_attributes, status);

{ All attributes must be valid to create a table.

    IF status.normal THEN
      allocate_table (p_form_table_definition);
      IF status.normal THEN
        p_form_table_definition^ := form_table_definition;
      IFEND;
    IFEND;
  PROCEND fdp$create_table;

?? TITLE := 'fdp$delete_table', EJECT ??
*copyc fdh$delete_table

  PROCEDURE [XDCL] fdp$delete_table
    (    form_identifier: fdt$form_identifier;
         table_name: ost$name;
     VAR status: ost$status);

    VAR
      name_exists: boolean,
      name_is_valid: boolean,
      p_form_definition: ^fdt$form_definition,
      p_form_status: ^fdt$form_status,
      p_form_table_definition: ^fdt$form_table_definition,
      p_form_table_definitions: ^array [1 .. * ] of fdt$form_table_definition,
      table_index: fdt$table_index,
      valid_name: ost$name;

?? NEWTITLE := 'condition_handler', EJECT ??

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           stack_frame_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
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$delete_table;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$delete_table;
        IFEND;

      ELSE
        ;
      CASEND;
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
    PROCEND condition_handler;

?? OLDTITLE, EJECT ??

    osp$establish_condition_handler (^condition_handler, FALSE);
    fdp$find_change_form_definition (form_identifier, p_form_status, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    p_form_definition := p_form_status^.p_form_definition;
    fdp$validate_name (table_name, p_form_definition^.processor, valid_name, name_is_valid);
    IF NOT name_is_valid THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

    p_form_table_definitions := p_form_status^.p_form_table_definitions;
    fdp$find_table_definition (valid_name, p_form_table_definitions,
          p_form_definition^.form_table_definitions.active_number, p_form_table_definition, table_index,
          name_exists);
    IF NOT name_exists THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$unknown_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

{ Move last table definition to position occupied by deleted terminal definition.
{ Then decrease number of active terminal definitions to exclude the last terminal defininition.

    p_form_table_definitions^ [table_index] := p_form_table_definitions^
          [p_form_definition^.form_table_definitions.active_number];
    p_form_definition^.form_table_definitions.active_number :=
          p_form_definition^.form_table_definitions.active_number - 1;

  PROCEND fdp$delete_table;

?? TITLE := 'fdp$get_table_attributes', EJECT ??
*copyc fdh$get_table_attributes

  PROCEDURE [XDCL] fdp$get_table_attributes
    (    form_identifier: fdt$form_identifier;
         table_name: ost$name;
     VAR get_table_attributes: fdt$get_table_attributes;
     VAR status: ost$status);

    VAR
      j: fdt$table_index,
      n: fdt$table_attribute_index,
      name_is_valid: boolean,
      name_exists: boolean,
      number_table_variables: fdt$number_table_variables,
      p_form_definition: ^fdt$form_definition,
      p_form_module: ^fdt$form_module,
      p_form_status: ^fdt$form_status,
      p_form_variable_definition: ^fdt$form_variable_definition,
      p_form_table_definition: ^fdt$form_table_definition,
      p_table_variable: ^fdt$table_variable,
      p_table_variables: ^array [1 .. * ] of fdt$table_variable,
      table_index: fdt$table_index,
      valid_name: ost$name;

?? NEWTITLE := 'condition_handler', EJECT ??

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           stack_frame_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
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$get_table_attributes;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT fdp$get_table_attributes;
        IFEND;

      ELSE
        ;
      CASEND;
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
    PROCEND condition_handler;

?? OLDTITLE, EJECT ??

    osp$establish_condition_handler (^condition_handler, FALSE);
    FOR n := LOWERBOUND (get_table_attributes) TO UPPERBOUND (get_table_attributes) DO
      get_table_attributes [n].get_value_status := fdc$unprocessed_get_value;
    FOREND;

    fdp$find_form_definition (form_identifier, p_form_status, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    p_form_definition := p_form_status^.p_form_definition;
    fdp$validate_name (table_name, p_form_definition^.processor, valid_name, name_is_valid);
    IF NOT name_is_valid THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

    fdp$find_table_definition (valid_name, p_form_status^.p_form_table_definitions,
          p_form_definition^.form_table_definitions.active_number, p_form_table_definition, table_index,
          name_exists);
    IF NOT name_exists THEN
      osp$set_status_abnormal (fdc$format_display_identifier, fde$unknown_table_name, table_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
      RETURN;
    IFEND;

    p_form_module := p_form_status^.p_form_module;
    table_index := 1;
    p_table_variables := fdp$ptr_table_variables (p_form_table_definition^.table_variables, p_form_module);

  /return_table_attributes/
    FOR n := LOWERBOUND (get_table_attributes) TO UPPERBOUND (get_table_attributes) DO
      CASE get_table_attributes [n].key OF

      = fdc$get_next_table_variable =
        get_table_attributes [n].get_value_status := fdc$undefined_value;

      /get_table_variable/
        FOR j := table_index TO p_form_table_definition^.table_variables.active_number DO
          get_table_attributes [n].variable_name := p_table_variables^ [j].name;
          get_table_attributes [n].get_value_status := fdc$user_defined_value;
          table_index := j + 1;
          EXIT /get_table_variable/;
        FOREND /get_table_variable/;

      = fdc$get_number_table_variables =
        get_table_attributes [n].get_value_status := fdc$user_defined_value;
        get_table_attributes [n].number_table_variables := p_form_table_definition^.table_variables.
              active_number;

      = fdc$get_stored_occurrence =
        get_table_attributes [n].stored_occurrence := p_form_table_definition^.stored_occurrence;
        IF p_form_table_definition^.stored_occurrence = fdc$system_occurrence THEN
          get_table_attributes [n].get_value_status := fdc$system_default_value;
        ELSE
          get_table_attributes [n].get_value_status := fdc$user_defined_value;
        IFEND;

      = fdc$get_unused_table_entry =
        get_table_attributes [n].get_value_status := fdc$undefined_value;

      = fdc$get_visible_occurrence =
        IF p_form_table_definition^.visible_occurrence_defined THEN
          get_table_attributes [n].visible_occurrence := p_form_table_definition^.visible_occurrence;
          get_table_attributes [n].get_value_status := fdc$user_defined_value;
        ELSE
          get_table_attributes [n].get_value_status := fdc$undefined_value;
        IFEND;

      ELSE

{ Invalid table attribute.

        osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_attribute,
              p_form_definition^.form_name, status);
        RETURN;

      CASEND;
    FOREND /return_table_attributes/;
  PROCEND fdp$get_table_attributes;

?? TITLE := 'change_table', EJECT ??

  PROCEDURE change_table
    (    p_form_status: ^fdt$form_status;
         p_form_table_definition: ^fdt$form_table_definition;
     VAR table_attributes: fdt$table_attributes;
     VAR status: ost$status);

    VAR
      j: fdt$table_variable_index,
      n: fdt$table_attribute_index,
      name_exists: boolean,
      name_is_valid: boolean,
      valid_name: ost$name,
      p_duplicate_table_definition: ^fdt$form_table_definition,
      p_form_definition: ^fdt$form_definition,
      p_form_module: ^fdt$form_module,
      p_form_table_definitions: ^array [1 .. * ] of fdt$form_table_definition,
      p_form_variable_definition: ^fdt$form_variable_definition,
      p_table_variable: ^fdt$table_variable,
      p_table_variables: ^array [1 .. * ] of fdt$table_variable,
      table_index: fdt$table_index,
      table_name: ost$name,
      table_variable_index: fdt$table_variable_index;

?? NEWTITLE := 'allocate_table_variable', EJECT ??

    PROCEDURE [INLINE] allocate_table_variable
      (VAR table_variables: fdt$table_variables;
       VAR p_table_variable: ^fdt$table_variable);

      VAR
        i: fdt$table_variable_index,
        number_table_variables: fdt$number_table_variables,
        p_form_module: ^fdt$form_module,
        p_new_table_variables: ^array [1 .. * ] of fdt$table_variable,
        p_old_table_variables: ^array [1 .. * ] of fdt$table_variable;

      p_form_module := p_form_status^.p_form_module;
      p_old_table_variables := fdp$ptr_table_variables (table_variables, p_form_module);
      IF p_old_table_variables = NIL THEN
        NEXT p_new_table_variables: [1 .. fdc$table_variables_to_expand] IN p_form_status^.p_form_module;
        IF p_new_table_variables = NIL THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$no_space_available, '', status);
          RETURN;
        IFEND;

        fdp$rel_table_variables (p_new_table_variables, p_form_module, table_variables);
        p_table_variable := ^p_new_table_variables^ [1];
        table_variables.active_number := 1;
        RETURN;
      IFEND;

{ An array for variables exists. Try to find an inactive entry.

      number_table_variables := table_variables.active_number;
      IF number_table_variables < table_variables.total_number THEN
        number_table_variables := number_table_variables + 1;
        table_variables.active_number := number_table_variables;
        p_table_variable := ^p_old_table_variables^ [number_table_variables];
        RETURN;
      IFEND;

{ Expand the array for table variables.

      NEXT p_new_table_variables: [1 .. fdc$table_variables_to_expand + number_table_variables] IN
            p_form_status^.p_form_module;
      IF p_new_table_variables = NIL THEN
        osp$set_status_abnormal (fdc$format_display_identifier, fde$no_space_available, '', status);
        RETURN;
      IFEND;

{ Copy old variables to new array.

      FOR i := 1 TO number_table_variables DO
        p_new_table_variables^ [i] := p_old_table_variables^ [i];
      FOREND;

      fdp$rel_table_variables (p_new_table_variables, p_form_module, table_variables);
      number_table_variables := number_table_variables + 1;
      table_variables.active_number := number_table_variables;
      p_table_variable := ^p_new_table_variables^ [number_table_variables];
    PROCEND allocate_table_variable;

?? OLDTITLE, EJECT ??
?? NEWTITLE := 'condition_handler', EJECT ??

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           stack_frame_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
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT change_table;
        IFEND;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          osp$set_status_abnormal (fdc$format_display_identifier, fde$bad_data_value, '', status);
          EXIT change_table;
        IFEND;

      ELSE
        ;
      CASEND;
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
    PROCEND condition_handler;

?? OLDTITLE, EJECT ??
    osp$establish_condition_handler (^condition_handler, FALSE);
    status.normal := TRUE;
    p_form_definition := p_form_status^.p_form_definition;
    p_form_module := p_form_status^.p_form_module;
    table_name := p_form_table_definition^.name;

  /change_table_attributes/
    FOR n := LOWERBOUND (table_attributes) TO UPPERBOUND (table_attributes) DO

    /process_table_attribute/
      BEGIN
        ;
        CASE table_attributes [n].key OF

        = fdc$add_table_variable =
          fdp$validate_name (table_attributes [n].variable_name, p_form_definition^.processor, valid_name,
                name_is_valid);
          IF NOT name_is_valid THEN
            osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_variable_name,
                  table_attributes [n].variable_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                  status);
            RETURN;
          IFEND;

{ Make sure there are no duplicate table_variable names. Loop through previous defined tables, and
{ then check the current table which is not yet allocated.

          p_form_table_definitions := p_form_status^.p_form_table_definitions;
          FOR table_index := 1 TO p_form_definition^.form_table_definitions.active_number DO
            IF (p_form_table_definitions^ [table_index].table_variables.active_number > 0) THEN
              p_table_variables := fdp$ptr_table_variables (p_form_table_definitions^ [table_index].
                    table_variables, p_form_module);
              FOR table_variable_index := 1 TO p_form_table_definitions^ [table_index].table_variables.
                    active_number DO
                IF (valid_name = p_table_variables^ [table_variable_index].name) THEN
                  osp$set_status_abnormal (fdc$format_display_identifier, fde$variable_name_exists,
                        table_attributes [n].variable_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                        status);
                  RETURN;
                IFEND;
              FOREND; { Table-variable loop. }
            IFEND;
          FOREND; { Table loop. }

          IF (p_form_table_definition^.table_variables.active_number > 0) THEN
            p_table_variables := fdp$ptr_table_variables (p_form_table_definition^.table_variables,
                  p_form_module);
            FOR table_variable_index := 1 TO p_form_table_definition^.table_variables.active_number DO
              IF (valid_name = p_table_variables^ [table_variable_index].name) THEN
                osp$set_status_abnormal (fdc$format_display_identifier, fde$variable_name_exists,
                      table_attributes [n].variable_name, status);
                osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                      status);
                RETURN;
              IFEND;
            FOREND;
          IFEND;

          allocate_table_variable (p_form_table_definition^.table_variables, p_table_variable);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          p_table_variable^.name := valid_name;
          p_table_variable^.variable_exists := FALSE;
          fdp$rel_table_objects (NIL, p_form_module, p_table_variable^.table_objects);
          table_attributes [n].put_value_status := fdc$put_value_accepted;

        = fdc$delete_table_variable =
          fdp$validate_name (table_attributes [n].variable_name, p_form_definition^.processor, valid_name,
                name_is_valid);
          IF NOT name_is_valid THEN
            osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_variable_name,
                  table_attributes [n].variable_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                  status);
            RETURN;
          IFEND;

          p_table_variables := fdp$ptr_table_variables (p_form_table_definition^.table_variables,
                p_form_module);

        /find_table_variable/
          FOR j := 1 TO p_form_table_definition^.table_variables.active_number DO
            p_table_variable := ^p_table_variables^ [j];
            IF p_table_variable^.name = valid_name THEN
              p_table_variable^ := p_table_variables^ [p_form_table_definition^.table_variables.
                    active_number];
              p_form_table_definition^.table_variables.active_number :=
                    p_form_table_definition^.table_variables.active_number - 1;
              table_attributes [n].put_value_status := fdc$put_value_accepted;
              EXIT /process_table_attribute/;
            IFEND;
          FOREND /find_table_variable/;

{ The variable to delete could not be found.

          osp$set_status_abnormal (fdc$format_display_identifier, fde$unknown_variable_name,
                table_attributes [n].variable_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name, status);
          RETURN;

        = fdc$new_table_name =
          fdp$validate_name (table_attributes [n].new_table_name, p_form_definition^.processor, valid_name,
                name_is_valid);
          IF NOT name_is_valid THEN
            osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_name,
                  table_attributes [n].new_table_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                  status);
            RETURN;
            table_name := valid_name;
          IFEND;

          fdp$find_table_definition (valid_name, p_form_status^.p_form_table_definitions,
                p_form_definition^.form_table_definitions.active_number, p_duplicate_table_definition,
                table_index, name_exists);
          IF name_exists THEN
            osp$set_status_abnormal (fdc$format_display_identifier, fde$table_name_exists,
                  table_attributes [n].new_table_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                  status);
            RETURN;
          IFEND;

          p_form_table_definition^.name := valid_name;
          table_attributes [n].put_value_status := fdc$put_value_accepted;

        = fdc$stored_occurrence =
          IF ((table_attributes [n].stored_occurrence < 1) OR
                (table_attributes [n].stored_occurrence > fdc$maximum_occurrence)) THEN
            osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_occurrence, '', status);
            osp$append_status_integer (osc$status_parameter_delimiter,
                  $INTEGER (table_attributes [n].stored_occurrence), 10, FALSE, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, table_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                  status);
            RETURN;
          IFEND;

          p_form_table_definition^.stored_occurrence := table_attributes [n].stored_occurrence;
          table_attributes [n].put_value_status := fdc$put_value_accepted;

        = fdc$unused_table_entry =
          table_attributes [n].put_value_status := fdc$put_value_accepted;

        = fdc$visible_occurrence =
          IF ((table_attributes [n].visible_occurrence < 1) OR
                (table_attributes [n].visible_occurrence > fdc$maximum_occurrence)) THEN
            osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_occurrence, '', status);
            osp$append_status_integer (osc$status_parameter_delimiter,
                  $INTEGER (table_attributes [n].visible_occurrence), 10, FALSE, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, table_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, p_form_definition^.form_name,
                  status);
            RETURN;
          IFEND;

          p_form_table_definition^.visible_occurrence_defined := TRUE;
          p_form_table_definition^.visible_occurrence := table_attributes [n].visible_occurrence;
          table_attributes [n].put_value_status := fdc$put_value_accepted;

        ELSE

{ Invalid table attribute.

          osp$set_status_abnormal (fdc$format_display_identifier, fde$invalid_table_attribute,
                p_form_definition^.form_name, status);
          RETURN;

        CASEND;
      END /process_table_attribute/;
    FOREND /change_table_attributes/;

  PROCEND change_table;


MODEND fdm$process_table;
