csdms / babelizer

Transform BMI-wrapped models into Python packages
https://babelizer.readthedocs.io
MIT License
4 stars 3 forks source link

Fortran: Consider padding model config file name #16

Open mdpiper opened 5 years ago

mdpiper commented 5 years ago

This issue (and I'm not convinced it is an issue) arises from a specific case, but the fix may still be general.

In the bmi_initialize method in bmi_interoperability.f90, the input config file path has an exact length; e.g., "gipl.cfg" has n=8 characters. When this string is passed to the underlying Fortran model (GIPL), it's input as a character*164 instead of a character (len=*). The problem is, when going from C to Fortran through the interoperability layer, the remaining 164-8=156 characters are filled out with garbage. I think this is unfortunate coding in GIPL, but I don't have the right to change it.

Instead, if we pad the config file name in bmi_initialize with spaces to BMI_MAX_VAR_NAME, when converting from C to Fortran, the string is truncated. It's still 164 characters in GIPL, but instead of garbage, there are spaces, which the model accepts.

Here's my change:

     integer (c_int), intent(in), value :: n
     character (len=1, kind=c_char), intent(in) :: config_file(n)
     integer (c_int) :: i, status
-    character (len=n, kind=c_char) :: config_file_
+    character (len=BMI_MAX_VAR_NAME, kind=c_char) :: config_file_

     ! Convert `config_file` from rank-1 array to scalar.
     do i = 1, n
        config_file_(i:i) = config_file(i)
     enddo

+    ! Pad with spaces to max size.
+    do i = n+1, BMI_MAX_VAR_NAME
+       config_file_(i:i) = ' '
+    enddo
+
     status = model_array(model_index)%initialize(config_file_)

I'm not sure this is a general solution, but I wanted to record it in case it's needed later.