!****s* Attributes/nf90_get_att_string ! ! NAME ! nf90_get_att_string - Read a string attribute from a netCDF data file. ! ! SYNOPSIS ! use ncdf ! ... ! call nf90_get_att_string(ncid, varid, attname, value) ! ! DESCRIPTION ! This subroutine reads string attribute data from the current netCDF file. ! It extends the functionality of nf90_get_att function by adding a ! possibility to read single string attributes (NF90_STRING) which at the ! moment netcdf-fortran library version 4.4.5 can not do. ! ! INPUTS ! ! OUTPUT ! value ! ! AUTHOR ! Leonid Butenko, Darmstadt, Germany ! ! COPYRIGHT ! ! Copyright (c) 2019 EUMETSAT ! ! All rights reserved. ! ! Permission is hereby granted, free of charge, to any person obtaining ! a copy of this software and associated documentation files (the ! "Software"), to deal in the Software without restriction, including ! without limitation the rights to use, copy, modify, merge, publish, ! distribute, sublicense, and/or sell copies of the Software, and to ! permit persons to whom the Software is furnished to do so, subject to ! the following conditions: ! ! The above copyright notice and this permission notice shall be ! included in all copies or substantial portions of the Software as well ! as in supporting documentation. ! ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ! EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ! NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ! LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ! OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ! WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ! !**** function nf90_get_att_string(ncid, varid, attname, value) result(status) use typeSizes use ncdf, not_this => nf90_get_att_string use netcdf, ONLY: nf90_inquire_attribute use, intrinsic :: iso_c_binding, ONLY: c_ptr, c_size_t, c_f_pointer, c_int implicit none Interface function nc_get_att_string(ncid, varid, name, ip) bind(c) use iso_c_binding, only: c_int, c_char, c_ptr integer(c_int), value :: ncid, varid character(kind=c_char), intent(in) :: name type(c_ptr), intent(out) :: ip integer(c_int ) :: nc_get_att_string end function nc_get_att_string end Interface Interface function strlen(s) bind(c, name='strlen') use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t implicit none !---- type(c_ptr), intent(in), value :: s integer(c_size_t) :: strlen end function strlen end Interface integer, intent(in ) :: ncid integer, intent(in ) :: varid character(len = *), intent(in ) :: attname character(len = *), intent(out) :: value integer :: status, xtype, nlen, attid, i integer(c_int) :: c_ncid, c_varid, c_status, c_nlen type(c_ptr) :: c_str character(len_trim(attname)+1) :: c_aname character, pointer :: f_str(:) status = nf90_inquire_attribute( ncid, varid, attname, xtype, nlen, attid ) if (status /= nf90_noerr) call ncdf_error_handler(status) if (xtype == NF90_STRING .AND. nlen == 1) then c_ncid = ncid c_varid = varid-1 ! C-library counts variables starting with 0 c_aname = trim(attname)//char(0) value = adjustl("") c_status = nc_get_att_string( c_ncid, c_varid, c_aname, c_str ) status = c_status call c_f_pointer( c_str, f_str, [strlen(c_str)] ) ! convert char array to string do i=1,size(f_str) value(i:i) = f_str(i) end do else !! all others status = nf90_get_att( ncid, varid, attname, value ) endif end function nf90_get_att_string