LLVM 24.0.0git
Unicode.cpp
Go to the documentation of this file.
1//===- llvm/Support/Unicode.cpp - Unicode character properties -*- 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// This file implements functions that allow querying certain properties of
10// Unicode characters.
11//
12//===----------------------------------------------------------------------===//
13
17
18namespace llvm {
19namespace sys {
20namespace unicode {
21
26
27/// Unicode code points of the categories L, M, N, P, S and Zs are considered
28/// printable.
29/// In addition, U+00AD SOFT HYPHEN is also considered printable, as
30/// it's actually displayed on most terminals. \return true if the character is
31/// considered printable.
32bool isPrintable(int UCS) {
33 static const UnicodeCharSet Printables(GeneratedPrintableRanges);
34 // Clang special cases 0x00AD (SOFT HYPHEN) which is rendered as an actual
35 // hyphen in most terminals.
36 return UCS == 0x00AD || Printables.contains(UCS);
37}
38
39/// Unicode code points of the Cf category are considered
40/// formatting characters.
41bool isFormatting(int UCS) {
43 return Format.contains(UCS);
44}
45
46/// Gets the number of positions a character is likely to occupy when output
47/// on a terminal ("character width"). This depends on the implementation of the
48/// terminal, and there's no standard definition of character width.
49/// The implementation defines it in a way that is expected to be compatible
50/// with a generic Unicode-capable terminal.
51/// \return Character width:
52/// * ErrorNonPrintableCharacter (-1) for non-printable characters (as
53/// identified by isPrintable);
54/// * 0 for non-spacing and enclosing combining marks;
55/// * 2 for CJK characters excluding halfwidth forms;
56/// * 1 for all remaining characters.
57static inline int charWidth(int UCS) {
58 if (!isPrintable(UCS))
60
61 static const UnicodeCharSet CombiningCharacters(
63
64 if (CombiningCharacters.contains(UCS))
65 return 0;
66
67 static const UnicodeCharSet DoubleWidthCharacters(
69
70 if (DoubleWidthCharacters.contains(UCS))
71 return 2;
72 return 1;
73}
74
75static bool isprintableascii(char c) { return c > 31 && c < 127; }
76
78 unsigned ColumnWidth = 0;
79 unsigned Length;
80 for (size_t i = 0, e = Text.size(); i < e; i += Length) {
82
83 // fast path for ASCII characters
84 if (Length == 1) {
85 if (!isprintableascii(Text[i]))
87 ColumnWidth += 1;
88 continue;
89 }
90
92 return ErrorInvalidUTF8;
93 UTF32 buf[1];
94 const UTF8 *Start = reinterpret_cast<const UTF8 *>(Text.data() + i);
95 UTF32 *Target = &buf[0];
96 if (conversionOK != ConvertUTF8toUTF32(&Start, Start + Length, &Target,
98 return ErrorInvalidUTF8;
99 int Width = charWidth(buf[0]);
100 if (Width < 0)
102 ColumnWidth += Width;
103 }
104 return ColumnWidth;
105}
106
107} // namespace unicode
108} // namespace sys
109} // namespace llvm
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target - Wrapper for Target specific information.
Holds a reference to an ordered array of UnicodeCharRange and allows to quickly check if a code point...
bool contains(uint32_t C) const
Returns true if the character set contains the Unicode code point C.
ArrayRef< UnicodeCharRange > CharRanges
@ ErrorNonPrintableCharacter
Definition Unicode.h:30
const UnicodeCharSet::CharRanges GeneratedDoubleWidthCharacterRanges
static bool isprintableascii(char c)
Definition Unicode.cpp:75
LLVM_ABI int columnWidthUTF8(StringRef Text)
Gets the number of positions the UTF8-encoded Text is likely to occupy when output on a terminal ("ch...
Definition Unicode.cpp:77
const UnicodeCharSet::CharRanges GeneratedFormatCharacterRanges
const UnicodeCharSet::CharRanges GeneratedCombiningCharacterRanges
const UnicodeCharSet::CharRanges GeneratedPrintableRanges
static int charWidth(int UCS)
Gets the number of positions a character is likely to occupy when output on a terminal ("character wi...
Definition Unicode.cpp:57
LLVM_ABI bool isFormatting(int UCS)
Unicode code points of the Cf category are considered formatting characters.
Definition Unicode.cpp:41
LLVM_ABI bool isPrintable(int UCS)
Determines if a character is likely to be displayed correctly on the terminal.
Definition Unicode.cpp:32
This is an optimization pass for GlobalISel generic memory operations.
unsigned char UTF8
Definition ConvertUTF.h:131
@ Length
Definition DWP.cpp:577
LLVM_ABI ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
Convert a partial UTF8 sequence to UTF32.
LLVM_ABI unsigned getNumBytesForUTF8(UTF8 firstByte)
unsigned int UTF32
Definition ConvertUTF.h:129
@ strictConversion
Definition ConvertUTF.h:156
@ conversionOK
Definition ConvertUTF.h:150