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
28
29/// Unicode code points that are considered characters. This function
30/// returns true for any code point defined by Unicode as a character, false for
31/// any code point defined as a non-character, as reserved, as a surrogate code
32/// point, or not defined at all.
33bool isCharacter(int UCS) {
34 static const UnicodeCharSet Character(GeneratedCharacterRanges);
35 return Character.contains(UCS);
36}
37
38/// Unicode code points of the categories L, M, N, P, S and Zs are considered
39/// printable.
40/// In addition, U+00AD SOFT HYPHEN is also considered printable, as
41/// it's actually displayed on most terminals. \return true if the character is
42/// considered printable.
43bool isPrintable(int UCS) {
44 static const UnicodeCharSet Printables(GeneratedPrintableRanges);
45 // Clang special cases 0x00AD (SOFT HYPHEN) which is rendered as an actual
46 // hyphen in most terminals.
47 return UCS == 0x00AD || Printables.contains(UCS);
48}
49
50/// Unicode code points of the Cc category are considered
51/// control characters.
52bool isControl(int UCS) {
54 return Control.contains(UCS);
55}
56
57/// Unicode code points of the Cf category are considered
58/// formatting characters.
59bool isFormatting(int UCS) {
61 return Format.contains(UCS);
62}
63
64/// Gets the number of positions a character is likely to occupy when output
65/// on a terminal ("character width"). This depends on the implementation of the
66/// terminal, and there's no standard definition of character width.
67/// The implementation defines it in a way that is expected to be compatible
68/// with a generic Unicode-capable terminal.
69/// \return Character width:
70/// * ErrorNonPrintableCharacter (-1) for non-printable characters (as
71/// identified by isPrintable);
72/// * 0 for non-spacing and enclosing combining marks;
73/// * 2 for CJK characters excluding halfwidth forms;
74/// * 1 for all remaining characters.
75static inline int charWidth(int UCS) {
76 if (!isPrintable(UCS))
78
79 static const UnicodeCharSet CombiningCharacters(
81
82 if (CombiningCharacters.contains(UCS))
83 return 0;
84
85 static const UnicodeCharSet DoubleWidthCharacters(
87
88 if (DoubleWidthCharacters.contains(UCS))
89 return 2;
90 return 1;
91}
92
93static bool isprintableascii(char c) { return c > 31 && c < 127; }
94
96 unsigned ColumnWidth = 0;
97 unsigned Length;
98 for (size_t i = 0, e = Text.size(); i < e; i += Length) {
100
101 // fast path for ASCII characters
102 if (Length == 1) {
103 if (!isprintableascii(Text[i]))
105 ColumnWidth += 1;
106 continue;
107 }
108
110 return ErrorInvalidUTF8;
111 UTF32 buf[1];
112 const UTF8 *Start = reinterpret_cast<const UTF8 *>(Text.data() + i);
113 UTF32 *Target = &buf[0];
114 if (conversionOK != ConvertUTF8toUTF32(&Start, Start + Length, &Target,
116 return ErrorInvalidUTF8;
117 int Width = charWidth(buf[0]);
118 if (Width < 0)
120 ColumnWidth += Width;
121 }
122 return ColumnWidth;
123}
124
125} // namespace unicode
126} // namespace sys
127} // 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
const UnicodeCharSet::CharRanges GeneratedCharacterRanges
static bool isprintableascii(char c)
Definition Unicode.cpp:93
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:95
LLVM_ABI bool isCharacter(int UCS)
Unicode code points that are considered characters.
Definition Unicode.cpp:33
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:75
LLVM_ABI bool isControl(int UCS)
Unicode code points of the Cc category are considered control characters.
Definition Unicode.cpp:52
LLVM_ABI bool isFormatting(int UCS)
Unicode code points of the Cf category are considered formatting characters.
Definition Unicode.cpp:59
LLVM_ABI bool isPrintable(int UCS)
Determines if a character is likely to be displayed correctly on the terminal.
Definition Unicode.cpp:43
const UnicodeCharSet::CharRanges GeneratedControlCharacterRanges
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