Index: palm/trunk/SOURCE/data_output_module.f90
===================================================================
--- palm/trunk/SOURCE/data_output_module.f90	(revision 4107)
+++ palm/trunk/SOURCE/data_output_module.f90	(revision 4113)
@@ -260,134 +260,400 @@
 ! Description:
 ! ------------
-!> Debugging output. Print contents of output database to terminal.
-!>
-!> @bug Routine currently not working properly due to changes in dimension/attribute value types.
-!> @todo Call routine via debug flag.
-!> @todo Use dim and var within loops to enhance readability of the code.
+!> Debugging output. Print contents of output database to debug_output_unit.
 !--------------------------------------------------------------------------------------------------!
 SUBROUTINE dom_database_debug_output
 
-   ! CHARACTER(LEN=100) ::  dim_string  !< list of dimension names as single string
-
+   CHARACTER(LEN=*), PARAMETER ::  separation_string = '---'                   !< string separating blocks in output
+   CHARACTER(LEN=50)           ::  format1                                     !< format for write statements
    CHARACTER(LEN=*), PARAMETER ::  routine_name = 'dom_database_debug_output'  !< name of this routine
 
-   ! INTEGER(iwp) ::  d     !< loop index
-   ! INTEGER(iwp) ::  f     !< loop index
-   ! INTEGER(iwp) ::  i     !< loop index
-   ! INTEGER(iwp) ::  ndim  !< number of dimensions
-   !
-   ! TYPE(dimension_type) ::  dim  !< dimension in file
-   !
-   ! TYPE(variable_type) ::  var   !< variable in file
-
-
-   CALL internal_message( 'error', routine_name // ': routine currently not available' )
-
-   ! nf = SIZE(files)
-   !
-   ! WRITE(*, '(A,I3)') '    number of files: ', nf
-   ! WRITE(*, '(A)')    '    files:'
-   ! DO  f = 1, nf
-   !    WRITE(*,'(//6X,A)') 'name: '//TRIM(files(f)%name)
-   !    WRITE(*,'(6X,A)') 'attributes:'
-   !    IF ( ALLOCATED(files(f)%attributes) )  THEN
-   !       CALL print_attributes( files(f)%attributes )
-   !    ELSE
-   !       WRITE(*,'(8X,A)') '--none--'
-   !    ENDIF
-   !
-   !    WRITE(*,'(/6X,A)') 'dimensions:'
-   !    IF ( ALLOCATED(files(f)%dimensions )  THEN
-   !       ndim = SIZE(files(f)%dimensions)
-   !       DO  d = 1, ndim
-   !
-   !          WRITE(*,'(/8X,A,I4/8X,A)') &
-   !             'name: '//TRIM(files(f)%dimensions(d)%name)//',  '// &
-   !             'length: ', files(f)%dimensions(d)%length, &
-   !             'values:'
-   !          IF ( ALLOCATED(files(f)%dimensions(d)%values_int32) )  THEN
-   !             WRITE(*,'(10X,5(I5,1X),A)') files(f)%dimensions(d)%values_int32(0:MIN(4,files(f)%dimensions(d)%length)), '...'
-   !          ELSE
-   !             WRITE(*,'(10X,5(F8.2,1X),A)')  &
-   !                files(f)%dimensions(d)%values_real64(0:MIN(4,files(f)%dimensions(d)%length)), '...'
-   !          ENDIF
-   !          IF ( ALLOCATED(files(f)%dimensions(d)%mask) )  THEN
-   !             WRITE(*,'(8X,A)') 'mask:'
-   !             WRITE(*,'(10X,5(L,1X),A)') files(f)%dimensions(d)%mask(0:MIN(4,files(f)%dimensions(d)%length)), '...'
-   !          ENDIF
-   !          WRITE(*,'(8X,A)') 'attributes:'
-   !          IF ( ALLOCATED( files(f)%dimensions(d)%attributes ) )  THEN
-   !             CALL print_attributes( files(f)%dimensions(d)%attributes )
-   !          ELSE
-   !             WRITE(*,'(10X,A)') '--none--'
-   !          ENDIF
-   !
-   !       ENDDO
-   !    ELSE
-   !       WRITE(*,'(8X,A)') '--none--'
-   !    ENDIF
-   !
-   !    WRITE(*,'(/6X,A)') 'variables:'
-   !    IF ( ALLOCATED(files(f)%variables) )  THEN
-   !       ndim = SIZE(files(f)%variables)
-   !       DO  d = 1, ndim
-   !          dim_string = '('
-   !          DO  i = 1, SIZE(files(f)%variables(d)%dimension_names)
-   !             dim_string = TRIM(dim_string)//' '//TRIM(files(f)%variables(d)%dimension_names(i))
-   !          ENDDO
-   !          dim_string = TRIM(dim_string)//')'
-   !          WRITE(*,'(/8X,A)') &
-   !             'name: '//TRIM(files(f)%variables(d)%name)//TRIM(dim_string)
-   !          WRITE(*,'(/8X,A)') &
-   !             'type: '//TRIM(files(f)%variables(d)%data_type)
-   !          WRITE(*,'(8X,A)') &
-   !             'ID: '
-   !          WRITE(*,'(8X,A)') 'attributes:'
-   !          IF ( ALLOCATED( files(f)%variables(d)%attributes ) )  THEN
-   !             CALL print_attributes( files(f)%variables(d)%attributes )
-   !          ELSE
-   !             WRITE(*,'(10X,A)') '--none--'
-   !          ENDIF
-   !       ENDDO
-   !    ELSE
-   !       WRITE(*,'(8X,A)') '--none--'
-   !    ENDIF
-   !
-   !    WRITE(*,'(4X,40("#"))')
-   !
-   ! ENDDO
-   !
-   ! CONTAINS
-   !
-   !    !------------------------------------------------------------------------!
-   !    ! Description:
-   !    ! ------------
-   !    !> Print given list of attributes.
-   !    !------------------------------------------------------------------------!
-   !    SUBROUTINE print_attributes( attributes )
-   !
-   !       INTEGER(iwp) ::  a     !< loop index
-   !       INTEGER(iwp) ::  natt  !< number of attributes
-   !
-   !       TYPE(attribute_type), DIMENSION(:), INTENT(IN) ::  attributes  !< list of attributes
-   !
-   !       natt = SIZE(attributes)
-   !       DO  a = 1, natt
-   !          IF ( TRIM(attributes(a)%data_type) == 'int32' )  THEN
-   !             WRITE(*,'(10X,A,1X,I10)') &
-   !                '"'//TRIM(attributes(a)%name)//'" = ', &
-   !                attributes(a)%value_int32
-   !          ELSEIF (  TRIM(attributes(a)%data_type) == 'real32' )  THEN
-   !             WRITE(*,'(10X,A,1X,F10.3)') &
-   !                '"'//TRIM(attributes(a)%name)//'" = ', &
-   !                attributes(a)%value_real64
-   !          ELSEIF (  TRIM(attributes(a)%data_type) == 'char' )  THEN
-   !             WRITE(*,'(10X,A,1X,A)') &
-   !                '"'//TRIM(attributes(a)%name)//'" = ', &
-   !                '"'//TRIM(attributes(a)%value_char)//'"'
-   !          ENDIF
-   !       ENDDO
-   !
-   !    END SUBROUTINE print_attributes
+   INTEGER            ::  f                       !< loop index
+   INTEGER, PARAMETER ::  indent_depth = 3        !< space per indentation
+   INTEGER            ::  indent_level            !< indentation level
+   INTEGER, PARAMETER ::  max_keyname_length = 6  !< length of longest key name
+   INTEGER            ::  natt                    !< number of attributes
+   INTEGER            ::  ndim                    !< number of dimensions
+   INTEGER            ::  nvar                    !< number of variables
+
+
+   CALL internal_message( 'debug', routine_name // ': write data base to debug output' )
+
+   WRITE( debug_output_unit, '(A)' ) 'DOM data base:'
+   WRITE( debug_output_unit, '(A)' ) REPEAT( separation_string // ' ', 4 )
+
+   IF ( .NOT. ALLOCATED( files) )  THEN
+
+      WRITE( debug_output_unit, '(A)' ) 'database is empty'
+
+   ELSE
+
+      indent_level = 1
+      WRITE( format1, '(A,I3,A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A,T',        &
+                                        indent_level * indent_depth + 1 + max_keyname_length, &
+                                        ',(": ")'
+
+      nf = SIZE( files )
+      DO  f = 1, nf
+
+         natt = 0
+         ndim = 0
+         nvar = 0
+         IF ( ALLOCATED( files(f)%attributes ) ) natt = SIZE( files(f)%attributes )
+         IF ( ALLOCATED( files(f)%dimensions ) ) ndim = SIZE( files(f)%dimensions )
+         IF ( ALLOCATED( files(f)%variables  ) ) nvar = SIZE( files(f)%variables  )
+
+         WRITE( debug_output_unit, '(A)' ) 'file:'
+         WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) 'name', TRIM( files(f)%name )
+         WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) 'format', TRIM( files(f)%format )
+         WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) 'id', files(f)%id
+         WRITE( debug_output_unit, TRIM( format1 ) // ',L1)' ) 'is init', files(f)%is_init
+         WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) '#atts', natt
+         WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) '#dims', ndim
+         WRITE( debug_output_unit, TRIM( format1 ) // ',I7)' ) '#vars', nvar
+
+         IF ( natt /= 0 )  CALL print_attributes( indent_level, files(f)%attributes )
+         IF ( ndim /= 0 )  CALL print_dimensions( indent_level, files(f)%dimensions )
+         IF ( nvar /= 0 )  CALL print_variables( indent_level, files(f)%variables )
+
+         WRITE( debug_output_unit, '(/A/)' ) REPEAT( separation_string // ' ', 4 )
+
+      ENDDO
+
+   ENDIF
+
+   CONTAINS
+
+      !--------------------------------------------------------------------------------------------!
+      ! Description:
+      ! ------------
+      !> Print list of attributes.
+      !--------------------------------------------------------------------------------------------!
+      SUBROUTINE print_attributes( indent_level, attributes )
+
+         CHARACTER(LEN=50) ::  format1  !< format for write statements
+         CHARACTER(LEN=50) ::  format2  !< format for write statements
+
+         INTEGER             ::  i                       !< loop index
+         INTEGER, INTENT(IN) ::  indent_level            !< indentation level
+         INTEGER, PARAMETER  ::  max_keyname_length = 6  !< length of longest key name
+         INTEGER             ::  nelement                !< number of elements to print
+
+         TYPE(attribute_type), DIMENSION(:), INTENT(IN) ::  attributes  !< list of attributes
+
+
+         WRITE( format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A'
+         WRITE( format2, '(A,I3,A,I3,A)' ) &
+            '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', &
+            ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")'
+
+         WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) REPEAT( separation_string // ' ', 4 )
+         WRITE( debug_output_unit, TRIM( format1 ) // ')' ) 'attributes:'
+
+         nelement = SIZE( attributes )
+         DO  i = 1, nelement
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+               'name', TRIM( attributes(i)%name )
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+               'type', TRIM( attributes(i)%data_type )
+
+            IF ( TRIM( attributes(i)%data_type ) == 'char' )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+                  'value', TRIM( attributes(i)%value_char )
+            ELSEIF ( TRIM( attributes(i)%data_type ) == 'int8' )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I4)' ) &
+                  'value', attributes(i)%value_int8
+            ELSEIF ( TRIM( attributes(i)%data_type ) == 'int16' )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I6)' ) &
+                  'value', attributes(i)%value_int16
+            ELSEIF ( TRIM( attributes(i)%data_type ) == 'int32' )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I11)' ) &
+                  'value', attributes(i)%value_int32
+            ELSEIF ( TRIM( attributes(i)%data_type ) == 'real32' )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',E14.7)' ) &
+                  'value', attributes(i)%value_real32
+            ELSEIF (  TRIM(attributes(i)%data_type) == 'real64' )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)' ) &
+                  'value', attributes(i)%value_real64
+            ENDIF
+            IF ( i < nelement )  &
+               WRITE( debug_output_unit, TRIM( format1 ) // ')' ) separation_string
+         ENDDO
+
+      END SUBROUTINE print_attributes
+
+      !--------------------------------------------------------------------------------------------!
+      ! Description:
+      ! ------------
+      !> Print list of dimensions.
+      !--------------------------------------------------------------------------------------------!
+      SUBROUTINE print_dimensions( indent_level, dimensions )
+
+         CHARACTER(LEN=50) ::  format1  !< format for write statements
+         CHARACTER(LEN=50) ::  format2  !< format for write statements
+
+         INTEGER             ::  i                        !< loop index
+         INTEGER, INTENT(IN) ::  indent_level             !< indentation level
+         INTEGER             ::  j                        !< loop index
+         INTEGER, PARAMETER  ::  max_keyname_length = 15  !< length of longest key name
+         INTEGER             ::  nelement                 !< number of elements to print
+
+         LOGICAL ::  is_masked  !< true if dimension is masked
+
+         TYPE(dimension_type), DIMENSION(:), INTENT(IN) ::  dimensions  !< list of dimensions
+
+
+         WRITE( format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A'
+         WRITE( format2, '(A,I3,A,I3,A)' ) &
+            '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', &
+            ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")'
+
+         WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) REPEAT( separation_string // ' ', 4 )
+         WRITE( debug_output_unit, TRIM( format1 ) // ')' ) 'dimensions:'
+
+         nelement = SIZE( dimensions )
+         DO  i = 1, nelement
+            is_masked = dimensions(i)%is_masked
+
+            !-- Print general information
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+               'name', TRIM( dimensions(i)%name )
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+               'type', TRIM( dimensions(i)%data_type )
+            WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &
+               'id', dimensions(i)%id
+            WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &
+               'length', dimensions(i)%length
+            WRITE( debug_output_unit, TRIM( format2 ) // ',I7,A,I7)' ) &
+               'bounds', dimensions(i)%bounds(1), ',', dimensions(i)%bounds(2)
+            WRITE( debug_output_unit, TRIM( format2 ) // ',L1)' ) &
+               'is masked', dimensions(i)%is_masked
+
+            !-- Print information about mask
+            IF ( is_masked )  THEN
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &
+                  'masked length', dimensions(i)%length_mask
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',L1)', ADVANCE='no' ) &
+                  'mask', dimensions(i)%mask(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,L1)', ADVANCE='no' ) ',', dimensions(i)%mask(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I6)', ADVANCE='no' ) &
+                  'masked indices', dimensions(i)%masked_indices(0)
+               DO  j = 1, dimensions(i)%length_mask-1
+                  WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) &
+                     ',', dimensions(i)%masked_indices(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+            ENDIF
+
+            !-- Print saved values
+            IF ( ALLOCATED( dimensions(i)%values_int8 ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I4)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_int8(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,I4)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_int8(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',I4)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_int8(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,I4)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_int8(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ELSEIF ( ALLOCATED( dimensions(i)%values_int16 ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I6)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_int16(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_int16(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',I6)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_int16(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,I6)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_int16(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ELSEIF ( ALLOCATED( dimensions(i)%values_int32 ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_int32(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_int32(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_int32(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_int32(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ELSEIF ( ALLOCATED( dimensions(i)%values_intwp ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_intwp(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_intwp(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',I11)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_intwp(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,I11)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_intwp(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ELSEIF ( ALLOCATED( dimensions(i)%values_real32 ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',E14.7)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_real32(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,E14.7)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_real32(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',E14.7)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_real32(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,E14.7)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_real32(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ELSEIF ( ALLOCATED( dimensions(i)%values_real64 ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_real64(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_real64(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_real64(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_real64(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ELSEIF ( ALLOCATED( dimensions(i)%values_realwp ) )  THEN
+
+               WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &
+                  'values', dimensions(i)%values_realwp(dimensions(i)%bounds(1))
+               DO  j = dimensions(i)%bounds(1)+1, dimensions(i)%bounds(2)
+                  WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &
+                     ',', dimensions(i)%values_realwp(j)
+               ENDDO
+               WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               IF ( is_masked )  THEN
+                  WRITE( debug_output_unit, TRIM( format2 ) // ',E22.15)', ADVANCE='no' ) &
+                     'masked values', dimensions(i)%masked_values_realwp(0)
+                  DO  j = 1, dimensions(i)%length_mask-1
+                     WRITE( debug_output_unit, '(A,E22.15)', ADVANCE='no' ) &
+                        ',', dimensions(i)%masked_values_realwp(j)
+                  ENDDO
+                  WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+               ENDIF
+
+            ENDIF
+
+            IF ( ALLOCATED( dimensions(i)%attributes ) )  &
+               CALL print_attributes( indent_level+1, dimensions(i)%attributes )
+
+            IF ( i < nelement )  &
+               WRITE( debug_output_unit, TRIM( format1 ) // ')' ) separation_string
+         ENDDO
+
+      END SUBROUTINE print_dimensions
+
+      !--------------------------------------------------------------------------------------------!
+      ! Description:
+      ! ------------
+      !> Print list of variables.
+      !--------------------------------------------------------------------------------------------!
+      SUBROUTINE print_variables( indent_level, variables )
+
+         CHARACTER(LEN=50) ::  format1  !< format for write statements
+         CHARACTER(LEN=50) ::  format2  !< format for write statements
+
+         INTEGER             ::  i                        !< loop index
+         INTEGER, INTENT(IN) ::  indent_level             !< indentation level
+         INTEGER             ::  j                        !< loop index
+         INTEGER, PARAMETER  ::  max_keyname_length = 16  !< length of longest key name
+         INTEGER             ::  nelement                 !< number of elements to print
+
+         TYPE(variable_type), DIMENSION(:), INTENT(IN) ::  variables  !< list of variables
+
+
+         WRITE( format1, '(A,I3,A)' ) '(T', indent_level * indent_depth + 1, ',A'
+         WRITE( format2, '(A,I3,A,I3,A)' ) &
+            '(T', ( indent_level + 1 ) * indent_depth + 1, ',A,T', &
+            ( indent_level + 1 ) * indent_depth + 1 + max_keyname_length, ',(": ")'
+
+         WRITE( debug_output_unit, TRIM( format1 ) // ',A)' ) REPEAT( separation_string // ' ', 4 )
+         WRITE( debug_output_unit, TRIM( format1 ) // ')' ) 'variables:'
+
+         nelement = SIZE( variables )
+         DO  i = 1, nelement
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+               'name', TRIM( variables(i)%name )
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)' ) &
+               'type', TRIM( variables(i)%data_type )
+            WRITE( debug_output_unit, TRIM( format2 ) // ',I7)' ) &
+               'id', variables(i)%id
+            WRITE( debug_output_unit, TRIM( format2 ) // ',L1)' ) &
+               'is global', variables(i)%is_global
+
+            WRITE( debug_output_unit, TRIM( format2 ) // ',A)', ADVANCE='no' ) &
+               'dimension names', TRIM( variables(i)%dimension_names(1) )
+            DO  j = 2, SIZE( variables(i)%dimension_names )
+               WRITE( debug_output_unit, '(A,A)', ADVANCE='no' ) &
+                  ',', TRIM( variables(i)%dimension_names(j) )
+            ENDDO
+            WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+
+            WRITE( debug_output_unit, TRIM( format2 ) // ',I7)', ADVANCE='no' ) &
+               'dimension ids', variables(i)%dimension_ids(1)
+            DO  j = 2, SIZE( variables(i)%dimension_names )
+               WRITE( debug_output_unit, '(A,I7)', ADVANCE='no' ) &
+                  ',', variables(i)%dimension_ids(j)
+            ENDDO
+            WRITE( debug_output_unit, '(A)' )  ''  ! write line-end
+
+            IF ( ALLOCATED( variables(i)%attributes ) )  &
+               CALL print_attributes( indent_level+1, variables(i)%attributes )
+            IF ( i < nelement )  &
+               WRITE( debug_output_unit, TRIM( format1 ) // ')' ) separation_string
+         ENDDO
+
+      END SUBROUTINE print_variables
 
 END SUBROUTINE dom_database_debug_output
@@ -1892,5 +2158,5 @@
 
             IF ( return_value == 0  .AND.  ALLOCATED( file%variables(d)%attributes ) )  THEN
-               !-- Write variable attribures
+               !-- Write variable attributes
                DO  a = 1, SIZE( file%variables(d)%attributes )
                   return_value = write_attribute( file%format, file%id, file%name, &
@@ -2044,5 +2310,5 @@
 
    END SELECT
-   
+
    IF ( output_return_value /= 0 )  THEN
       return_value = output_return_value
@@ -3224,5 +3490,5 @@
    DO  f = 1, nf
       IF ( TRIM( filename ) == TRIM( files(f)%name ) )  THEN
-         
+
          IF ( .NOT. files(f)%is_init )  THEN
             return_value = 1
@@ -3234,5 +3500,5 @@
             EXIT
          ENDIF
-         
+
          file_id     = files(f)%id
          file_format = files(f)%format
