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