?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Determine Layout of Command File Lines' ??
MODULE clm$determine_line_layout;

{
{ PURPOSE:
{   This module contains the procedure that determines the layout of lines from command files according to
{   the attributes of the command file.
{

?? NEWTITLE := 'Global Declarations' ??
?? NEWTITLE := 'Line Layout', EJECT ??
*copyc clt$line_layout
?? OLDTITLE, EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amt$line_number
*copyc amt$max_record_length
*copyc amt$record_type
*copyc amt$statement_identifier
*copyc cle$ecc_command_processing
*copyc ost$status
?? POP ??
*copyc fsp$set_file_reference_abnormal

?? TITLE := 'clp$determine_line_layout', EJECT ??

  PROCEDURE [XDCL, #GATE] clp$determine_line_layout
    (    file_reference: fst$file_reference;
*IF NOT $true(osv$unix)
         record_type: amt$record_type,
         max_record_length: amt$max_record_length;
         line_number_present: boolean;
         line_number: amt$line_number;
         statement_identifier_present: boolean;
         statement_identifier: amt$statement_identifier;
*IFEND
     VAR line_layout: clt$line_layout;
     VAR status: ost$status);

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

    PROCEDURE [INLINE] improper_command_file_attr
      (    error: string ( * ));

      fsp$set_file_reference_abnormal (file_reference, cle$improper_command_file_attr, amc$open_req, error,
            status);
      EXIT clp$determine_line_layout;

    PROCEND improper_command_file_attr;
?? OLDTITLE, EJECT ??
*IFEND

    status.normal := TRUE;

*IF NOT $true(osv$unix)
    IF NOT (line_number_present OR statement_identifier_present) THEN
*IFEND

{ No Line Numbers or Statement Identifiers

*IF NOT $true(osv$unix)
      IF (record_type = amc$ansi_fixed) AND (max_record_length <= clc$max_command_line_size) THEN
        IF max_record_length < clc$min_text_line_element_size THEN
          improper_command_file_attr ('record length less than minimum command line length');
        IFEND;
        line_layout.physical_line_size := max_record_length;
      ELSE
*IFEND
        line_layout.physical_line_size := clc$max_command_line_size;
*IF NOT $true(osv$unix)
      IFEND;
*IFEND
      line_layout.element [1].kind := clc$text_line_element;
      line_layout.element [1].size := line_layout.physical_line_size;
      line_layout.element [2].kind := clc$null_line_element;
      line_layout.element [2].size := 0;
      line_layout.element [3].kind := clc$null_line_element;
      line_layout.element [3].size := 0;

*IF NOT $true(osv$unix)
    ELSEIF NOT statement_identifier_present THEN
      IF line_number.location = 1 THEN

{ Line Numbers on left

        IF (record_type = amc$ansi_fixed) AND (max_record_length <=
              (clc$max_command_line_size + line_number.length)) THEN
          IF max_record_length < (line_number.length + clc$min_text_line_element_size) THEN
            improper_command_file_attr ('line_number leaves insufficient space in record for data');
          IFEND;
          line_layout.physical_line_size := max_record_length;
        ELSE
          line_layout.physical_line_size := clc$max_command_line_size + line_number.length;
        IFEND;
        line_layout.element [1].kind := clc$line_number_line_element;
        line_layout.element [1].size := line_number.length;
        line_layout.element [2].kind := clc$text_line_element;
        line_layout.element [2].size := line_layout.physical_line_size - line_number.length;
        line_layout.element [3].kind := clc$null_line_element;
        line_layout.element [3].size := 0;

      ELSE

{ Line Numbers on right

        IF line_number.location > (clc$max_command_line_size + 1) THEN
          improper_command_file_attr ('record data length greater than maximum command line length');
        ELSEIF (record_type = amc$ansi_fixed) AND (max_record_length <>
              (line_number.location + line_number.length - 1)) THEN
          improper_command_file_attr ('line_number location conflicts with fixed record length');
        ELSEIF line_number.location < (clc$min_text_line_element_size + 1) THEN
          improper_command_file_attr ('line_number leaves insufficient space in record for data');
        IFEND;

        line_layout.physical_line_size := line_number.location + line_number.length - 1;
        line_layout.element [1].kind := clc$text_line_element;
        line_layout.element [1].size := line_number.location - 1;
        line_layout.element [2].kind := clc$line_number_line_element;
        line_layout.element [2].size := line_number.length;
        line_layout.element [3].kind := clc$null_line_element;
        line_layout.element [3].size := 0;
      IFEND;

    ELSEIF NOT line_number_present THEN
      IF statement_identifier.location = 1 THEN

{ Statement Identifiers on left

        IF (record_type = amc$ansi_fixed) AND (max_record_length <=
              (clc$max_command_line_size + statement_identifier.length)) THEN
          IF max_record_length < (statement_identifier.length + clc$min_text_line_element_size) THEN
            improper_command_file_attr ('statement_identifier leaves insufficient space in record for data');
          IFEND;
          line_layout.physical_line_size := max_record_length;
        ELSE
          line_layout.physical_line_size := clc$max_command_line_size + statement_identifier.length;
        IFEND;
        line_layout.element [1].kind := clc$statement_id_line_element;
        line_layout.element [1].size := statement_identifier.length;
        line_layout.element [2].kind := clc$text_line_element;
        line_layout.element [2].size := line_layout.physical_line_size - statement_identifier.length;
        line_layout.element [3].kind := clc$null_line_element;
        line_layout.element [3].size := 0;

      ELSE

{ Statement Identifiers on right

        IF statement_identifier.location > (clc$max_command_line_size + 1) THEN
          improper_command_file_attr ('record data length greater than maximum command line length');
        ELSEIF (record_type = amc$ansi_fixed) AND (max_record_length <>
              (statement_identifier.location + statement_identifier.length - 1)) THEN
          improper_command_file_attr ('statement_identifier location conflicts with fixed record length');
        ELSEIF statement_identifier.location < (clc$min_text_line_element_size + 1) THEN
          improper_command_file_attr ('statement_identifier leaves insufficient space in record for data');
        IFEND;

        line_layout.physical_line_size := statement_identifier.location + statement_identifier.length - 1;
        line_layout.element [1].kind := clc$text_line_element;
        line_layout.element [1].size := statement_identifier.location - 1;
        line_layout.element [2].kind := clc$statement_id_line_element;
        line_layout.element [2].size := statement_identifier.length;
        line_layout.element [3].kind := clc$null_line_element;
        line_layout.element [3].size := 0;
      IFEND;

    ELSE

{ Both Line Numbers and Statement Identifiers

      IF line_number.location = 1 THEN
        IF statement_identifier.location <= line_number.length THEN
          improper_command_file_attr ('statement_identifier overlaps line_number');

        ELSEIF statement_identifier.location = (line_number.length + 1) THEN

{ Line Numbers, Statement Identifiers on left

          IF (record_type = amc$ansi_fixed) AND (max_record_length <=
                (clc$max_command_line_size + line_number.length + statement_identifier.length)) THEN
            IF (max_record_length - line_number.length - statement_identifier.length) <
                  clc$min_text_line_element_size THEN
              improper_command_file_attr (
                    'line_number and statement_identifier leave insufficient space in record for data');
            IFEND;
            line_layout.physical_line_size := max_record_length;
          ELSE
            line_layout.physical_line_size := clc$max_command_line_size + line_number.length +
                  statement_identifier.length;
          IFEND;
          line_layout.element [1].kind := clc$line_number_line_element;
          line_layout.element [1].size := line_number.length;
          line_layout.element [2].kind := clc$statement_id_line_element;
          line_layout.element [2].size := statement_identifier.length;
          line_layout.element [3].kind := clc$text_line_element;
          line_layout.element [3].size := line_layout.physical_line_size - line_number.length -
                statement_identifier.length;

        ELSE

{ Line Numbers on left, Statement Identifiers on right

          IF (statement_identifier.location - line_number.length) < (clc$min_text_line_element_size + 1) THEN
            improper_command_file_attr (
                  'line_number and statement_identifier leave insufficient space in record for data');
          ELSEIF (record_type = amc$ansi_fixed) AND (max_record_length <>
                (statement_identifier.location + statement_identifier.length - 1)) THEN
            improper_command_file_attr ('statement_identifier location conflicts with fixed record length');
          IFEND;

          line_layout.physical_line_size := statement_identifier.location + statement_identifier.length - 1;
          line_layout.element [1].kind := clc$line_number_line_element;
          line_layout.element [1].size := line_number.length;
          line_layout.element [2].kind := clc$text_line_element;
          line_layout.element [2].size := line_layout.physical_line_size - line_number.length -
                statement_identifier.length;
          line_layout.element [3].kind := clc$statement_id_line_element;
          line_layout.element [3].size := statement_identifier.length;
        IFEND;

      ELSEIF statement_identifier.location = 1 THEN
        IF line_number.location <= statement_identifier.length THEN
          improper_command_file_attr ('line_number overlaps statement_identifier');

        ELSEIF line_number.location = (statement_identifier.length + 1) THEN

{ Statement Identifiers, Line Numbers on left

          IF (record_type = amc$ansi_fixed) AND (max_record_length <=
                (clc$max_command_line_size + statement_identifier.length + line_number.length)) THEN
            IF (max_record_length - statement_identifier.length - line_number.length) <
                  clc$min_text_line_element_size THEN
              improper_command_file_attr (
                    'statement_identifier and line_number leave insufficient space in record for data');
            IFEND;
            line_layout.physical_line_size := max_record_length;
          ELSE
            line_layout.physical_line_size := clc$max_command_line_size + statement_identifier.length +
                  line_number.length;
          IFEND;

          line_layout.element [1].kind := clc$statement_id_line_element;
          line_layout.element [1].size := statement_identifier.length;
          line_layout.element [2].kind := clc$line_number_line_element;
          line_layout.element [2].size := line_number.length;
          line_layout.element [3].kind := clc$text_line_element;
          line_layout.element [3].size := line_layout.physical_line_size - statement_identifier.length -
                line_number.length;

        ELSE

{ Statement Identifiers on left, Line Numbers on right

          IF (line_number.location - statement_identifier.length) < (clc$min_text_line_element_size + 1) THEN
            improper_command_file_attr (
                  'statement_identifier and line_number leave insufficient space in record for data');
          ELSEIF (record_type = amc$ansi_fixed) AND (max_record_length <>
                (line_number.location + line_number.length - 1)) THEN
            improper_command_file_attr ('line_number location conflicts with fixed record length');
          IFEND;

          line_layout.physical_line_size := line_number.location + line_number.length - 1;
          line_layout.element [1].kind := clc$statement_id_line_element;
          line_layout.element [1].size := statement_identifier.length;
          line_layout.element [2].kind := clc$text_line_element;
          line_layout.element [2].size := line_layout.physical_line_size - statement_identifier.length -
                line_number.length;
          line_layout.element [3].kind := clc$line_number_line_element;
          line_layout.element [3].size := line_number.length;
        IFEND;

      ELSEIF line_number.location < statement_identifier.location THEN

{ Line Numbers, Statement Identifiers on right

        IF line_number.location <= clc$min_text_line_element_size THEN
          improper_command_file_attr ('line_number leaves insufficient space in record for data');
        ELSEIF line_number.location > (clc$max_command_line_size + 1) THEN
          improper_command_file_attr ('record data length exceeds maximum command line length');
        ELSEIF statement_identifier.location < (line_number.location + line_number.length) THEN
          improper_command_file_attr ('statement_identifier overlaps line_identifer');
        ELSEIF statement_identifier.location > (line_number.location + line_number.length) THEN
          improper_command_file_attr ('line_number and statement_identifier both on right but not contiguous')
                ;
        ELSEIF (record_type = amc$ansi_fixed) AND (max_record_length <>
              (statement_identifier.location + statement_identifier.length - 1)) THEN
          improper_command_file_attr ('statement_identifier location conflicts with fixed record length');
        IFEND;

        line_layout.physical_line_size := statement_identifier.location + statement_identifier.length - 1;
        line_layout.element [1].kind := clc$text_line_element;
        line_layout.element [1].size := line_layout.physical_line_size - line_number.length -
              statement_identifier.length;
        line_layout.element [2].kind := clc$line_number_line_element;
        line_layout.element [2].size := line_number.length;
        line_layout.element [3].kind := clc$statement_id_line_element;
        line_layout.element [3].size := statement_identifier.length;

      ELSE

{ Statement Identifiers, Line Numbers on right

        IF statement_identifier.location <= clc$min_text_line_element_size THEN
          improper_command_file_attr ('statement_identifier leaves insufficient space in record for data');
        ELSEIF statement_identifier.location > (clc$max_command_line_size + 1) THEN
          improper_command_file_attr ('record data length exceeds maximum command line length');
        ELSEIF line_number.location < (statement_identifier.location + statement_identifier.length) THEN
          improper_command_file_attr ('line_number overlaps statement_identifier');
        ELSEIF line_number.location > (statement_identifier.location + statement_identifier.length) THEN
          improper_command_file_attr ('statement_identifier and line_number both on right but not contiguous')
                ;
        ELSEIF (record_type = amc$ansi_fixed) AND (max_record_length <>
              (line_number.location + line_number.length - 1)) THEN
          improper_command_file_attr ('line_number location conflicts with fixed record length');
        IFEND;

        line_layout.physical_line_size := line_number.location + line_number.length - 1;
        line_layout.element [1].kind := clc$text_line_element;
        line_layout.element [1].size := line_layout.physical_line_size - statement_identifier.length -
              line_number.length;
        line_layout.element [2].kind := clc$statement_id_line_element;
        line_layout.element [2].size := statement_identifier.length;
        line_layout.element [3].kind := clc$line_number_line_element;
        line_layout.element [3].size := line_number.length;
      IFEND;
    IFEND;
*IFEND

  PROCEND clp$determine_line_layout;

MODEND clm$determine_line_layout;
