1 //===-- runtime/tools.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "tools.h"
10 #include <algorithm>
11 #include <cstring>
12
13 namespace Fortran::runtime {
14
TrimTrailingSpaces(const char * s,std::size_t n)15 std::size_t TrimTrailingSpaces(const char *s, std::size_t n) {
16 while (n > 0 && s[n - 1] == ' ') {
17 --n;
18 }
19 return n;
20 }
21
SaveDefaultCharacter(const char * s,std::size_t length,const Terminator & terminator)22 OwningPtr<char> SaveDefaultCharacter(
23 const char *s, std::size_t length, const Terminator &terminator) {
24 if (s) {
25 auto *p{static_cast<char *>(AllocateMemoryOrCrash(terminator, length + 1))};
26 std::memcpy(p, s, length);
27 p[length] = '\0';
28 return OwningPtr<char>{p};
29 } else {
30 return OwningPtr<char>{};
31 }
32 }
33
CaseInsensitiveMatch(const char * value,std::size_t length,const char * possibility)34 static bool CaseInsensitiveMatch(
35 const char *value, std::size_t length, const char *possibility) {
36 for (; length-- > 0; ++possibility) {
37 char ch{*value++};
38 if (ch >= 'a' && ch <= 'z') {
39 ch += 'A' - 'a';
40 }
41 if (*possibility != ch) {
42 if (*possibility != '\0' || ch != ' ') {
43 return false;
44 }
45 // Ignore trailing blanks (12.5.6.2 p1)
46 while (length-- > 0) {
47 if (*value++ != ' ') {
48 return false;
49 }
50 }
51 return true;
52 }
53 }
54 return *possibility == '\0';
55 }
56
IdentifyValue(const char * value,std::size_t length,const char * possibilities[])57 int IdentifyValue(
58 const char *value, std::size_t length, const char *possibilities[]) {
59 if (value) {
60 for (int j{0}; possibilities[j]; ++j) {
61 if (CaseInsensitiveMatch(value, length, possibilities[j])) {
62 return j;
63 }
64 }
65 }
66 return -1;
67 }
68
ToFortranDefaultCharacter(char * to,std::size_t toLength,const char * from)69 void ToFortranDefaultCharacter(
70 char *to, std::size_t toLength, const char *from) {
71 std::size_t len{std::strlen(from)};
72 std::memcpy(to, from, std::max(toLength, len));
73 if (len < toLength) {
74 std::memset(to + len, ' ', toLength - len);
75 }
76 }
77
78 } // namespace Fortran::runtime
79