xref: /llvm-project/flang/runtime/tools.cpp (revision 1f8790050b0e99e7b46cc69518aa84f46f50738e)
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 
15 OwningPtr<char> SaveDefaultCharacter(
16     const char *s, std::size_t length, const Terminator &terminator) {
17   if (s) {
18     auto *p{static_cast<char *>(AllocateMemoryOrCrash(terminator, length + 1))};
19     std::memcpy(p, s, length);
20     p[length] = '\0';
21     return OwningPtr<char>{p};
22   } else {
23     return OwningPtr<char>{};
24   }
25 }
26 
27 static bool CaseInsensitiveMatch(
28     const char *value, std::size_t length, const char *possibility) {
29   for (; length-- > 0; ++possibility) {
30     char ch{*value++};
31     if (ch >= 'a' && ch <= 'z') {
32       ch += 'A' - 'a';
33     }
34     if (*possibility != ch) {
35       if (*possibility != '\0' || ch != ' ') {
36         return false;
37       }
38       // Ignore trailing blanks (12.5.6.2 p1)
39       while (length-- > 0) {
40         if (*value++ != ' ') {
41           return false;
42         }
43       }
44       return true;
45     }
46   }
47   return *possibility == '\0';
48 }
49 
50 int IdentifyValue(
51     const char *value, std::size_t length, const char *possibilities[]) {
52   if (value) {
53     for (int j{0}; possibilities[j]; ++j) {
54       if (CaseInsensitiveMatch(value, length, possibilities[j])) {
55         return j;
56       }
57     }
58   }
59   return -1;
60 }
61 
62 void ToFortranDefaultCharacter(
63     char *to, std::size_t toLength, const char *from) {
64   std::size_t len{std::strlen(from)};
65   std::memcpy(to, from, std::max(toLength, len));
66   if (len < toLength) {
67     std::memset(to + len, ' ', toLength - len);
68   }
69 }
70 
71 } // namespace Fortran::runtime
72