Skip to content

Commit a1b1b66

Browse files
committed
use cstring not string.h, add terminator, fill buffer with space
take copyBufferAndPad() out of anonymous namespace, so it can be called in other places.
1 parent 17cf436 commit a1b1b66

File tree

3 files changed

+42
-24
lines changed

3 files changed

+42
-24
lines changed

flang/include/flang/Runtime/time-intrinsic.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@
99
// Defines the API between compiled code and the implementations of time-related
1010
// intrinsic subroutines in the runtime library.
1111

12+
// time-intrinsic.h
13+
#ifndef TIME_INTRINSIC_H
14+
#define TIME_INTRINSIC_H
15+
16+
#include <cstddef>
17+
18+
void copyBufferAndPad(
19+
char *dest, std::size_t destChars, char *buffer, std::size_t len);
20+
21+
#endif // TIME_INTRINSIC_H
22+
1223
#ifndef FORTRAN_RUNTIME_TIME_INTRINSIC_H_
1324
#define FORTRAN_RUNTIME_TIME_INTRINSIC_H_
1425

flang/runtime/extensions.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@
1010
// extensions that will eventually be implemented in Fortran.
1111

1212
#include "flang/Runtime/extensions.h"
13+
#include "terminator.h"
1314
#include "flang/Runtime/command.h"
1415
#include "flang/Runtime/descriptor.h"
1516
#include "flang/Runtime/io-api.h"
16-
#include <string.h>
17+
#include "flang/Runtime/time-intrinsic.h" // copyBufferAndPad
18+
#include <cstring>
1719

1820
#ifdef _WIN32
1921
#define WIN32_LEAN_AND_MEAN
2022
#define NOMINMAX
2123
#include <windows.h>
2224

25+
#include <cstdlib> // wcstombs_s
2326
#include <lmcons.h> // UNLEN=256
24-
#include <stdlib.h> // wcstombs_s
2527
#include <wchar.h> // wchar_t cast to LPWSTR
2628
#pragma comment(lib, "Advapi32.lib") // Link Advapi32.lib for GetUserName
2729
#define LOGIN_NAME_MAX UNLEN
@@ -30,10 +32,9 @@ inline int getlogin_r(char *buf, size_t bufSize) {
3032
wchar_t w_username[UNLEN + 1];
3133
DWORD nameLen = UNLEN + 1;
3234

33-
if (GetUserNameW(w_username, &nameLen)) {
35+
if (GetUserName(w_username, &nameLen)) {
3436
// Convert the wchar_t string to a regular C string using wcstombs_s
35-
if (wcstombs_s(nullptr, buf, sizeof(w_username), w_username, _TRUNCATE) !=
36-
0) {
37+
if (wcstombs_s(nullptr, buf, bufSize, w_username, _TRUNCATE) != 0) {
3738
// Conversion failed
3839
return -1;
3940
}
@@ -49,7 +50,11 @@ inline int getlogin_r(char *buf, size_t bufSize) {
4950
#include <unistd.h>
5051
#else
5152
// System is not posix-compliant
52-
inline int getlogin_r(char *buf, size_t bufsize) { return -1; }
53+
inline int getlogin_r(char *buf, size_t bufSize) {
54+
std::memset(buf, ' ', bufSize - 1);
55+
buf[bufSize - 1] = '\0';
56+
return 0;
57+
}
5358
#endif
5459

5560
extern "C" {
@@ -78,15 +83,13 @@ void FORTRAN_PROCEDURE_NAME(getarg)(
7883

7984
void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) {
8085
std::array<char, LOGIN_NAME_MAX + 1> str;
86+
8187
int error = getlogin_r(str.data(), str.size());
82-
assert(error == 0 && "getlogin_r returned an error");
88+
Terminator terminator{__FILE__, __LINE__};
89+
RUNTIME_CHECK(terminator, error == 0);
8390

84-
// Trim space from right/end
85-
int i = str.size();
86-
while (' ' == str[--i]) {
87-
str[i] = 0;
88-
}
89-
strncpy(reinterpret_cast<char *>(arg), str.data(), length);
91+
copyBufferAndPad(
92+
reinterpret_cast<char *>(arg), length, str.data(), str.size());
9093
}
9194

9295
} // namespace Fortran::runtime

flang/runtime/time-intrinsic.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@
3939
// overload will have a dummy parameter whose type indicates whether or not it
4040
// should be preferred. Any other parameters required for SFINAE should have
4141
// default values provided.
42+
43+
// outside anonymous namespace, function reused
44+
void copyBufferAndPad(
45+
char *dest, std::size_t destChars, char *buffer, std::size_t len) {
46+
auto copyLen{std::min(len, destChars)};
47+
std::memcpy(dest, buffer, copyLen);
48+
for (auto i{copyLen}; i < destChars; ++i) {
49+
dest[i] = ' ';
50+
}
51+
}
52+
4253
namespace {
4354
// Types for the dummy parameter indicating the priority of a given overload.
4455
// We will invoke our helper with an integer literal argument, so the overload
@@ -279,29 +290,22 @@ static void GetDateAndTime(Fortran::runtime::Terminator &terminator, char *date,
279290

280291
static constexpr std::size_t buffSize{16};
281292
char buffer[buffSize];
282-
auto copyBufferAndPad{
283-
[&](char *dest, std::size_t destChars, std::size_t len) {
284-
auto copyLen{std::min(len, destChars)};
285-
std::memcpy(dest, buffer, copyLen);
286-
for (auto i{copyLen}; i < destChars; ++i) {
287-
dest[i] = ' ';
288-
}
289-
}};
293+
290294
if (date) {
291295
auto len = std::strftime(buffer, buffSize, "%Y%m%d", &localTime);
292-
copyBufferAndPad(date, dateChars, len);
296+
copyBufferAndPad(date, dateChars, buffer, len);
293297
}
294298
if (time) {
295299
auto len{std::snprintf(buffer, buffSize, "%02d%02d%02d.%03jd",
296300
localTime.tm_hour, localTime.tm_min, localTime.tm_sec, ms)};
297-
copyBufferAndPad(time, timeChars, len);
301+
copyBufferAndPad(time, timeChars, buffer, len);
298302
}
299303
if (zone) {
300304
// Note: this may leave the buffer empty on many platforms. Classic flang
301305
// has a much more complex way of doing this (see __io_timezone in classic
302306
// flang).
303307
auto len{std::strftime(buffer, buffSize, "%z", &localTime)};
304-
copyBufferAndPad(zone, zoneChars, len);
308+
copyBufferAndPad(zone, zoneChars, buffer, len);
305309
}
306310
if (values) {
307311
auto typeCode{values->type().GetCategoryAndKind()};

0 commit comments

Comments
 (0)