comparison flang/runtime/character.cpp @ 173:0572611fdcc8 llvm10 llvm12

reorgnization done
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 11:55:54 +0900
parents
children 2e18cbf3894f
comparison
equal deleted inserted replaced
172:9fbae9c8bf63 173:0572611fdcc8
1 //===-- runtime/character.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 "character.h"
10 #include "descriptor.h"
11 #include "terminator.h"
12 #include <algorithm>
13 #include <cstring>
14
15 namespace Fortran::runtime {
16
17 template <typename C>
18 inline int CompareToBlankPadding(const C *x, std::size_t chars) {
19 for (; chars-- > 0; ++x) {
20 if (*x < ' ') {
21 return -1;
22 }
23 if (*x > ' ') {
24 return 1;
25 }
26 }
27 return 0;
28 }
29
30 template <typename C, int shift>
31 static int Compare(
32 const C *x, const C *y, std::size_t xBytes, std::size_t yBytes) {
33 auto minBytes{std::min(xBytes, yBytes)};
34 if constexpr (shift == 0) {
35 // don't use for kind=2 or =4, that would fail on little-endian machines
36 int cmp{std::memcmp(x, y, minBytes)};
37 if (cmp < 0) {
38 return -1;
39 }
40 if (cmp > 0) {
41 return 1;
42 }
43 if (xBytes == yBytes) {
44 return 0;
45 }
46 x += minBytes;
47 y += minBytes;
48 } else {
49 for (std::size_t n{minBytes >> shift}; n-- > 0; ++x, ++y) {
50 if (*x < *y) {
51 return -1;
52 }
53 if (*x > *y) {
54 return 1;
55 }
56 }
57 }
58 if (int cmp{CompareToBlankPadding(x, (xBytes - minBytes) >> shift)}) {
59 return cmp;
60 }
61 return -CompareToBlankPadding(y, (yBytes - minBytes) >> shift);
62 }
63
64 extern "C" {
65
66 void RTNAME(CharacterConcatenate)(Descriptor & /*temp*/,
67 const Descriptor & /*operand*/, const char * /*sourceFile*/,
68 int /*sourceLine*/) {
69 // TODO
70 }
71
72 void RTNAME(CharacterConcatenateScalar)(
73 Descriptor & /*temp*/, const char * /*from*/, std::size_t /*byteLength*/) {
74 // TODO
75 }
76
77 void RTNAME(CharacterAssign)(Descriptor & /*lhs*/, const Descriptor & /*rhs*/,
78 const char * /*sourceFile*/, int /*sourceLine*/) {
79 // TODO
80 }
81
82 int RTNAME(CharacterCompareScalar)(const Descriptor &, const Descriptor &) {
83 // TODO real soon once there's type codes for character(kind=2 & 4)
84 return 0;
85 }
86
87 int RTNAME(CharacterCompareScalar1)(
88 const char *x, const char *y, std::size_t xBytes, std::size_t yBytes) {
89 return Compare<char, 0>(x, y, xBytes, yBytes);
90 }
91
92 int RTNAME(CharacterCompareScalar2)(const char16_t *x, const char16_t *y,
93 std::size_t xBytes, std::size_t yBytes) {
94 return Compare<char16_t, 1>(x, y, xBytes, yBytes);
95 }
96
97 int RTNAME(CharacterCompareScalar4)(const char32_t *x, const char32_t *y,
98 std::size_t xBytes, std::size_t yBytes) {
99 return Compare<char32_t, 2>(x, y, xBytes, yBytes);
100 }
101
102 void RTNAME(CharacterCompare)(
103 Descriptor &, const Descriptor &, const Descriptor &) {
104 // TODO real soon once there's type codes for character(kind=2 & 4)
105 }
106
107 std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes,
108 std::size_t offset, const char *rhs, std::size_t rhsBytes) {
109 if (auto n{std::min(lhsBytes - offset, rhsBytes)}) {
110 std::memcpy(lhs + offset, rhs, n);
111 offset += n;
112 }
113 return offset;
114 }
115
116 void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset) {
117 if (bytes > offset) {
118 std::memset(lhs + offset, ' ', bytes - offset);
119 }
120 }
121 }
122 } // namespace Fortran::runtime