@@ -61,35 +61,22 @@ RT_EXT_API_GROUP_BEGIN
6161void RTDEF (Rename)(const Descriptor &path1, const Descriptor &path2,
6262 const Descriptor *status, const char *sourceFile, int line) {
6363 Terminator terminator{sourceFile, line};
64- #if !defined(RT_DEVICE_COMPILATION)
65- // Get the raw strings (null-terminated)
66- char *pathSrc{EnsureNullTerminated (
67- path1.OffsetElement (), path1.ElementBytes (), terminator)};
68- char *pathDst{EnsureNullTerminated (
69- path2.OffsetElement (), path2.ElementBytes (), terminator)};
70- char *srcFilePath = pathSrc;
71- char *dstFilePath = pathDst;
7264
73- // Trim trailing blanks (if string have not been null-terminated)
74- if (!IsNullTerminated (path1.OffsetElement (), path1.ElementBytes ())) {
75- auto srcTrimPos{TrimTrailingSpaces (pathSrc, path1.ElementBytes ())};
76- char *srcPathTrim{
77- static_cast <char *>(alloca ((srcTrimPos + 1 )))};
78- std::memcpy (srcPathTrim, pathSrc, srcTrimPos);
79- srcPathTrim[srcTrimPos] = ' \0 ' ;
80- srcFilePath = srcPathTrim;
81- }
82- if (!IsNullTerminated (path2.OffsetElement (), path2.ElementBytes ())) {
83- auto dstTrimPos{TrimTrailingSpaces (pathDst, path2.ElementBytes ())};
84- char *dstPathTrim{
85- static_cast <char *>(alloca ((dstTrimPos + 1 )))};
86- std::memcpy (dstPathTrim, pathDst, dstTrimPos);
87- dstPathTrim[dstTrimPos] = ' \0 ' ;
88- dstFilePath = dstPathTrim;
89- }
65+ // Semantics for character strings: A null character (CHAR(0)) can be used to
66+ // mark the end of the names in PATH1 and PATH2; otherwise, trailing blanks in
67+ // the file names are ignored.
68+ // (https://gcc.gnu.org/onlinedocs/gfortran/RENAME.html)
69+ #if !defined(RT_DEVICE_COMPILATION)
70+ // Trim tailing spaces, respect presences of null character when doing so.
71+ auto pathSrc{SaveDefaultCharacter (path1.OffsetElement (),
72+ TrimTrailingSpaces (path1.OffsetElement (), path1.ElementBytes ()),
73+ terminator)};
74+ auto pathDst{SaveDefaultCharacter (path2.OffsetElement (),
75+ TrimTrailingSpaces (path2.OffsetElement (), path2.ElementBytes ()),
76+ terminator)};
9077
91- // We simply call rename(2) from POSIX
92- int result{rename (srcFilePath, dstFilePath )};
78+ // We can now simply call rename(2) from POSIX.
79+ int result{rename (pathSrc. get (), pathDst. get () )};
9380 if (status) {
9481 // When an error has happened,
9582 int errorCode{0 }; // Assume success
@@ -99,14 +86,6 @@ void RTDEF(Rename)(const Descriptor &path1, const Descriptor &path2,
9986 }
10087 StoreIntToDescriptor (status, errorCode, terminator);
10188 }
102-
103- // Deallocate memory if EnsureNullTerminated dynamically allocated memory
104- if (pathSrc != path1.OffsetElement ()) {
105- FreeMemory (pathSrc);
106- }
107- if (pathDst != path2.OffsetElement ()) {
108- FreeMemory (pathDst);
109- }
11089#else // !defined(RT_DEVICE_COMPILATION)
11190 terminator.Crash (" RENAME intrinsic is only supported on host devices" );
11291#endif // !defined(RT_DEVICE_COMPILATION)
0 commit comments