Commit bc86c996 authored by Thomas Jahns's avatar Thomas Jahns 🤸
Browse files

Fix string passing through F2003 ISO C interface.

* The previous implementation was not thread safe (accidental SAVE
  attribute) and handled string arguments of full length without a
  c_null_char terminator incorrectly.
parent 2713ecc5
......@@ -112,7 +112,8 @@ $wrapperResultVarName = 'f_result'
# Template definitions #############################################################################
####################################################################################################
$argumentTemplates = [
$argumentTemplates =
[
{ #Dummy for declarations using foo(void).
:regex => '^\s*void\s*$',
:placeholders => %w[],
......@@ -294,27 +295,24 @@ $argumentTemplates = [
:placeholders => %w[name],
:dummyName => '<name>_dummy',
:acceptAs => 'character(kind = c_char, len = *), intent(inout) :: <name>_dummy',
:helperVars => "character(kind = c_char) :: <name>_temp(len(<name>_dummy))\n" +
"integer :: <name>_i\n" +
"logical :: <name>_padding = .true.",
:precallStatements => "do <name>_i = len(<name>_dummy), 1, -1\n" +
"\tif(<name>_dummy(<name>_i:<name>_i) /= ' ') <name>_padding = .false.\n" +
"\tif(<name>_padding) then\n" +
"\t\t<name>_temp(<name>_i) = c_null_char\n" +
"\telse\n" +
:helperVars => "character(kind = c_char) :: <name>_temp(len(<name>_dummy) + 1)\n" +
"integer :: <name>_i",
:precallStatements => "<name>_temp(len(<name>_dummy) + 1) = c_null_char\n" +
"do <name>_i = len(<name>_dummy), 1, -1\n" +
"\tif(<name>_dummy(<name>_i:<name>_i) /= ' ') exit\n" +
"\t<name>_temp(<name>_i) = c_null_char\n" +
"end do\n" +
"do <name>_i = <name>_i, 1, -1\n" +
"\t\t<name>_temp(<name>_i) = <name>_dummy(<name>_i:<name>_i)\n" +
"\tend if\n" +
"end do",
:callExpression => '<name>_temp',
:passAs => 'character(kind = c_char) :: <name>_dummy(*)',
:postcallStatements => "<name>_padding = .false.\n" +
"do <name>_i = 1, len(<name>_dummy)\n" +
"\tif(<name>_temp(<name>_i) == c_null_char) <name>_padding = .true.\n" +
"\tif(<name>_padding) then\n" +
"\t\t<name>_dummy(<name>_i:<name>_i) = ' '\n" +
"\telse\n" +
"\t\t<name>_dummy(<name>_i:<name>_i) = <name>_temp(<name>_i)\n" +
"\tend if\n" +
:postcallStatements => "do <name>_i = 1, len(<name>_dummy)\n" +
"\tif(<name>_temp(<name>_i) == c_null_char) exit\n" +
"\t<name>_dummy(<name>_i:<name>_i) = <name>_temp(<name>_i)\n" +
"end do\n" +
"do <name>_i = <name>_i, len(<name>_dummy)\n" +
"\t<name>_dummy(<name>_i:<name>_i) = ' '\n" +
"end do"
}, { #const char* Safe passing of an input string.
:regex => '^\s*(const\s+char|char\sconst)\s*\*\s*(?<name>\w+)\s*$',
......@@ -363,7 +361,7 @@ $argumentTemplates = [
:passAs => 'type(c_ptr), value :: <name>_dummy',
:postcallStatements => ''
}
]
]
$returnTypeTemplates = [
{ #void
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment