Mercurial > hg > CbC > CbC_llvm
view flang/runtime/tools.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
line wrap: on
line source
//===-- runtime/tools.cpp ---------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "tools.h" #include "terminator.h" #include <algorithm> #include <cstdint> #include <cstring> namespace Fortran::runtime { std::size_t TrimTrailingSpaces(const char *s, std::size_t n) { while (n > 0 && s[n - 1] == ' ') { --n; } return n; } OwningPtr<char> SaveDefaultCharacter( const char *s, std::size_t length, const Terminator &terminator) { if (s) { auto *p{static_cast<char *>(AllocateMemoryOrCrash(terminator, length + 1))}; std::memcpy(p, s, length); p[length] = '\0'; return OwningPtr<char>{p}; } else { return OwningPtr<char>{}; } } static bool CaseInsensitiveMatch( const char *value, std::size_t length, const char *possibility) { for (; length-- > 0; ++possibility) { char ch{*value++}; if (ch >= 'a' && ch <= 'z') { ch += 'A' - 'a'; } if (*possibility != ch) { if (*possibility != '\0' || ch != ' ') { return false; } // Ignore trailing blanks (12.5.6.2 p1) while (length-- > 0) { if (*value++ != ' ') { return false; } } return true; } } return *possibility == '\0'; } int IdentifyValue( const char *value, std::size_t length, const char *possibilities[]) { if (value) { for (int j{0}; possibilities[j]; ++j) { if (CaseInsensitiveMatch(value, length, possibilities[j])) { return j; } } } return -1; } void ToFortranDefaultCharacter( char *to, std::size_t toLength, const char *from) { std::size_t len{std::strlen(from)}; std::memcpy(to, from, std::max(toLength, len)); if (len < toLength) { std::memset(to + len, ' ', toLength - len); } } void CheckConformability(const Descriptor &to, const Descriptor &x, Terminator &terminator, const char *funcName, const char *toName, const char *xName) { if (x.rank() == 0) { return; // scalar conforms with anything } int rank{to.rank()}; if (x.rank() != rank) { terminator.Crash( "Incompatible array arguments to %s: %s has rank %d but %s has rank %d", funcName, toName, rank, xName, x.rank()); } else { for (int j{0}; j < rank; ++j) { auto toExtent{static_cast<std::int64_t>(to.GetDimension(j).Extent())}; auto xExtent{static_cast<std::int64_t>(x.GetDimension(j).Extent())}; if (xExtent != toExtent) { terminator.Crash("Incompatible array arguments to %s: dimension %d of " "%s has extent %" PRId64 " but %s has extent %" PRId64, funcName, j, toName, toExtent, xName, xExtent); } } } } void CheckIntegerKind(Terminator &terminator, int kind, const char *intrinsic) { if (kind < 1 || kind > 16 || (kind & (kind - 1)) != 0) { terminator.Crash("%s: bad KIND=%d argument", intrinsic, kind); } } } // namespace Fortran::runtime