reimplement character properties and character manipulation via ICU

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
Ivailo Monev 2019-11-21 18:18:37 +00:00
parent df7225de36
commit fa34c080f6
20 changed files with 403 additions and 23142 deletions

View file

@ -13,7 +13,7 @@ services:
- xvfb
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq ninja-build libpcre3-dev libssl-dev zlib1g-dev libc6-dev libpng-dev libjpeg-dev libtiff-dev libmng-dev libcups2-dev libfreetype6-dev libfontconfig1-dev libdbus-1-dev unixodbc-dev libpq-dev libpqtypes-dev libmysqld-dev libaio-dev libwrap0-dev liblz4-dev libsqlite3-dev xorg-dev
- sudo apt-get install -qq ninja-build libpcre3-dev libssl-dev zlib1g-dev libc6-dev libpng-dev libjpeg-dev libtiff-dev libmng-dev libcups2-dev libfreetype6-dev libfontconfig1-dev libdbus-1-dev libicu-dev unixodbc-dev libpq-dev libpqtypes-dev libmysqld-dev libaio-dev libwrap0-dev liblz4-dev libsqlite3-dev xorg-dev
- wget 'http://mirrors.kernel.org/ubuntu/pool/universe/libz/libzstd/libzstd1_1.3.1+dfsg-1~ubuntu0.16.04.1_amd64.deb'
- wget 'http://mirrors.kernel.org/ubuntu/pool/universe/libz/libzstd/libzstd1-dev_1.3.1+dfsg-1~ubuntu0.16.04.1_amd64.deb'
- sudo dpkg -i *.deb

View file

@ -225,6 +225,15 @@ set_package_properties(ZLIB PROPERTIES
TYPE REQUIRED
)
# v4.6 required for unorm2_getDecomposition
find_package(ICU 4.6)
set_package_properties(ICU PROPERTIES
PURPOSE "Required for locales support"
DESCRIPTION "Mature, widely used libraries providing Unicode and Globalization support"
URL "http://site.icu-project.org/"
TYPE REQUIRED
)
# v0.7.3+ required for ZSTD_getDecompressedSize()
find_package(ZSTD 0.7.3)
set_package_properties(ZSTD PROPERTIES

View file

@ -0,0 +1,56 @@
# - Try to find International Components for Unicode
# Once done this will define
#
# ICU_FOUND - system has ICU
# ICU_INCLUDES - the ICU include directory
# ICU_LIBRARIES - The libraries needed to use ICU
#
# Copyright (c) 2015-2019, Ivailo Monev, <xakepa10@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
if(ICU_INCLUDES AND ICU_LIBRARIES)
set(ICU_FIND_QUIETLY TRUE)
endif()
if(NOT WIN32)
include(FindPkgConfig)
pkg_check_modules(PC_ICU QUIET icu-i18n)
endif()
find_path(ICU_INCLUDES
NAMES
unicode/unistr.h
HINTS
$ENV{ICUDIR}/include
${PC_ICU_INCLUDEDIR}
${INCLUDE_INSTALL_DIR}
)
find_library(ICU_LIBRARIES
icui18n
HINTS
$ENV{ICUDIR}/lib
${PC_ICU_LIBDIR}
${LIB_INSTALL_DIR}
)
find_library(ICUUC_LIBRARIES
icuuc
HINTS
$ENV{ICUDIR}/lib
${PC_ICU_LIBDIR}
${LIB_INSTALL_DIR}
)
if(ICU_LIBRARIES AND ICUUC_LIBRARIES)
set(ICU_LIBRARIES ${ICU_LIBRARIES} ${ICUUC_LIBRARIES})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ICU
VERSION_VAR PC_ICU_VERSION
REQUIRED_VARS ICU_LIBRARIES ICUUC_LIBRARIES ICU_INCLUDES
)
mark_as_advanced(ICU_INCLUDES ICU_LIBRARIES ICUUC_LIBRARIES)

View file

@ -8,7 +8,7 @@ pkgdesc='C++ toolkit derived from the Qt 4.8 framework'
arch=('i686' 'x86_64')
url='https://github.com/fluxer/katie'
license=('LGPL' 'FDL' 'custom')
depends=('openssl' 'zlib' 'cups' 'libice' 'libsm' 'pcre' 'libxcursor'
depends=('openssl' 'zlib' 'cups' 'libice' 'libsm' 'pcre' 'libxcursor' 'icu'
'libxext' 'libxfixes' 'libxi' 'libxinerama' 'libxrandr' 'libxrender'
'libx11' 'fontconfig' 'freetype2' 'libmng' 'zstd')
makedepends=('cmake' 'git' 'postgresql' 'libmariadbclient' 'unixodbc' 'unifdef')

View file

@ -9,13 +9,13 @@ Standards-Version: 4.9.0
Build-Depends: debhelper (>= 9~), g++, libssl-dev, zlib1g-dev, libzstd-dev,
libc6-dev, libpng-dev, libjpeg-dev, libtiff5-dev, libmng-dev, libcups2-dev,
libfreetype6-dev, libfontconfig1-dev, libpcre3-dev, libdbus-1-dev,
unixodbc-dev, libpq-dev, libpqtypes-dev, libmariadbclient-dev,
unixodbc-dev, libpq-dev, libpqtypes-dev, libmariadbclient-dev, libicu-dev,
libmariadbd-dev, libaio-dev, libsqlite3-dev, xorg-dev, cmake, git
Package: katie-git
Architecture: i386 amd64
Depends: ${shlibs:Depends}, ${misc:Depends}, openssl, zlib1g, libzstd1, libc6,
libpng16-16, libjpeg62-turbo, libtiffxx5, libmng1, libcups2, libfreetype6,
libfontconfig1, libpcre3, libdbus-1-3, libsqlite3-0
libfontconfig1, libpcre3, libdbus-1-3, libsqlite3-0, libicu63
Recommends: unixodbc, libpq5, libmariadbclient, xorg
Description: C++ toolkit derived from the Qt 4.8 framework

View file

@ -54,39 +54,7 @@ def printifrange(frommap):
switchmap = {}
rangemap = {}
if 'digit' in sys.argv:
for line in readlines('extracted/DerivedNumericValues.txt'):
tablesplit = line.split(';')
codepoint = tablesplit[0].strip()
value = tablesplit[3].strip()
if '/' in value:
# TODO: handle fraction
continue
mapdecideinsert(switchmap, rangemap, value, codepoint)
printswitch(switchmap)
printifrange(rangemap)
elif 'joining' in sys.argv:
for line in readlines('extracted/DerivedJoiningType.txt'):
tablesplit = line.split(';')
codepoint = tablesplit[0].strip()
value = tablesplit[1].strip()
if value == 'C':
value = 'QChar::Causing'
elif value == 'D':
value = 'QChar::Dual'
elif value == 'R':
value = 'QChar::Right'
elif value == 'L':
value = 'QChar::Left'
elif value == 'T':
value = 'QChar::Transparent'
else:
print('Unhandled joining type: %s' % value)
sys.exit(2)
mapdecideinsert(switchmap, rangemap, value, codepoint)
printswitch(switchmap)
printifrange(rangemap)
elif 'combining' in sys.argv:
if 'combining' in sys.argv:
for line in readlines('extracted/DerivedCombiningClass.txt'):
tablesplit = line.split(';')
codepoint = tablesplit[0].strip()
@ -208,23 +176,6 @@ elif 'combining' in sys.argv:
mapdecideinsert(switchmap, rangemap, value, codepoint)
printswitch(switchmap)
printifrange(rangemap)
elif 'mirror' in sys.argv:
for line in readlines('BidiMirroring.txt'):
tablesplit = line.split(';')
codepoint = tablesplit[0].strip()
value = tablesplit[1].strip()
mapdecideinsert(switchmap, rangemap, '0x%s' % value, codepoint)
printswitch(switchmap)
printifrange(rangemap)
elif 'version' in sys.argv:
for line in readlines('DerivedAge.txt'):
tablesplit = line.split(';')
codepoint = tablesplit[0].strip()
value = tablesplit[1].strip()
value = 'QChar::Unicode_%s' % value.replace('.', '_')
mapdecideinsert(switchmap, rangemap, value, codepoint)
printswitch(switchmap)
printifrange(rangemap)
elif 'word' in sys.argv:
# only some are supported by harfbuzz
supported = [
@ -348,7 +299,7 @@ elif 'special' in sys.argv:
print(' 0x%s, // %s' % (codepoint, value.replace('_', '')))
scriptslist.append(value)
else:
print('''usage: <digit|joining|combining|mirror|version|word|sentence|line|script|special>
print('''usage: <combining|word|sentence|line|script|special>
Data is from https://unicode.org/Public/12.1.0/ucd/UCD.zip''')
sys.exit(1)

View file

@ -1,93 +0,0 @@
## utf8proc license ##
**utf8proc** is a software package originally developed
by Jan Behrens and the rest of the Public Software Group, who
deserve nearly all of the credit for this library, that is now maintained by the Julia-language developers. Like the original utf8proc,
whose copyright and license statements are reproduced below, all new
work on the utf8proc library is licensed under the [MIT "expat"
license](http://opensource.org/licenses/MIT):
*Copyright &copy; 2014-2019 by Steven G. Johnson, Jiahao Chen, Tony Kelman, Jonas Fonseca, and other contributors listed in the git history.*
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
## Original utf8proc license ##
*Copyright (c) 2009, 2013 Public Software Group e. V., Berlin, Germany*
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
## Unicode data license ##
This software contains data (`utf8proc_data.c`) derived from processing
the Unicode data files. The following license applies to that data:
**COPYRIGHT AND PERMISSION NOTICE**
*Copyright (c) 1991-2007 Unicode, Inc. All rights reserved. Distributed
under the Terms of Use in http://www.unicode.org/copyright.html.*
Permission is hereby granted, free of charge, to any person obtaining a
copy of the Unicode data files and any associated documentation (the "Data
Files") or Unicode software and any associated documentation (the
"Software") to deal in the Data Files or Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, and/or sell copies of the Data Files or Software, and
to permit persons to whom the Data Files or Software are furnished to do
so, provided that (a) the above copyright notice(s) and this permission
notice appear with all copies of the Data Files or Software, (b) both the
above copyright notice(s) and this permission notice appear in associated
documentation, and (c) there is clear notice in each modified Data File or
in the Software as well as in the documentation associated with the Data
File(s) or Software that the data or software has been modified.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall
not be used in advertising or otherwise to promote the sale, use or other
dealings in these Data Files or Software without prior written
authorization of the copyright holder.
Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be
registered in some jurisdictions. All other trademarks and registered
trademarks mentioned herein are the property of their respective owners.

View file

@ -1,89 +0,0 @@
# utf8proc
[![Travis CI Status](https://travis-ci.org/JuliaStrings/utf8proc.png)](https://travis-ci.org/JuliaStrings/utf8proc)
[![AppVeyor status](https://ci.appveyor.com/api/projects/status/ivaa0v6ikxrmm5r6?svg=true)](https://ci.appveyor.com/project/StevenGJohnson/utf8proc)
[utf8proc](http://juliastrings.github.io/utf8proc/) is a small, clean C
library that provides Unicode normalization, case-folding, and other
operations for data in the [UTF-8
encoding](http://en.wikipedia.org/wiki/UTF-8). It was [initially
developed](http://www.public-software-group.org/utf8proc) by Jan
Behrens and the rest of the [Public Software
Group](http://www.public-software-group.org/), who deserve *nearly all
of the credit* for this package. With the blessing of the Public
Software Group, the [Julia developers](http://julialang.org/) have
taken over development of utf8proc, since the original developers have
moved to other projects.
(utf8proc is used for basic Unicode
support in the [Julia language](http://julialang.org/), and the Julia
developers became involved because they wanted to add Unicode 7 support and other features.)
(The original utf8proc package also includes Ruby and PostgreSQL plug-ins.
We removed those from utf8proc in order to focus exclusively on the C
library for the time being, but plan to add them back in or release them as separate packages.)
The utf8proc package is licensed under the
free/open-source [MIT "expat"
license](http://opensource.org/licenses/MIT) (plus certain Unicode
data governed by the similarly permissive [Unicode data
license](http://www.unicode.org/copyright.html#Exhibit1)); please see
the included `LICENSE.md` file for more detailed information.
## Quick Start
Typical users should download a [utf8proc release](http://juliastrings.github.io/utf8proc/releases/) rather than cloning directly from github.
For compilation of the C library, run `make`. You can also install the library and header file with `make install` (by default into `/usr/local/lib` and `/usr/local/bin`, but this can be changed by `make prefix=/some/dir`). `make check` runs some tests, and `make clean` deletes all of the generated files.
Alternatively, you can compile with `cmake`, e.g. by
```sh
mkdir build
cd build
cmake ..
make
```
### Using other compilers
The included `Makefile` supports GNU/Linux flavors and MacOS with `gcc`-like compilers; Windows users will typically use `cmake`.
For other Unix-like systems and other compilers, you may need to pass modified settings to `make` in order to use the correct compilation flags for building shared libraries on your system.
For HP-UX with HP's `aCC` compiler and GNU Make (installed as `gmake`), you can compile with
```
gmake CC=/opt/aCC/bin/aCC CFLAGS="+O2" PICFLAG="+z" C99FLAG="-Ae" WCFLAGS="+w" LDFLAG_SHARED="-b" SOFLAG="-Wl,+h"
```
To run `gmake install` you will need GNU coreutils for the `install` command, and you may want to pass `prefix=/opt libdir=/opt/lib/hpux32` or similar to change the installation location.
## General Information
The C library is found in this directory after successful compilation
and is named `libutf8proc.a` (for the static library) and
`libutf8proc.so` (for the dynamic library).
The Unicode version supported is 12.1.0.
For Unicode normalizations, the following options are used:
* Normalization Form C: `STABLE`, `COMPOSE`
* Normalization Form D: `STABLE`, `DECOMPOSE`
* Normalization Form KC: `STABLE`, `COMPOSE`, `COMPAT`
* Normalization Form KD: `STABLE`, `DECOMPOSE`, `COMPAT`
## C Library
The documentation for the C library is found in the `utf8proc.h` header file.
`utf8proc_map` is function you will most likely be using for mapping UTF-8
strings, unless you want to allocate memory yourself.
## To Do
See the Github [issues list](https://github.com/JuliaLang/utf8proc/issues).
## Contact
Bug reports, feature requests, and other queries can be filed at
the [utf8proc issues page on Github](https://github.com/JuliaLang/utf8proc/issues).
## See also
An independent Lua translation of this library, [lua-mojibake](https://github.com/differentprogramming/lua-mojibake), is also available.

View file

@ -1,27 +0,0 @@
```
U+0020 <-- all space characters (general category Zs)
U+0027 ' <-- left/right single quotation mark U+2018..2019,
modifier letter apostrophe U+02BC,
modifier letter vertical line U+02C8
U+002D - <-- all dash characters (general category Pd),
minus U+2212
U+002F / <-- fraction slash U+2044,
division slash U+2215
U+003A : <-- ratio U+2236
U+003C < <-- single left-pointing angle quotation mark U+2039,
left-pointing angle bracket U+2329,
left angle bracket U+3008
U+003E > <-- single right-pointing angle quotation mark U+203A,
right-pointing angle bracket U+232A,
right angle bracket U+3009
U+005C \ <-- set minus U+2216
U+005E ^ <-- modifier letter up arrowhead U+02C4,
modifier letter circumflex accent U+02C6,
caret U+2038,
up arrowhead U+2303
U+005F _ <-- all connector characters (general category Pc),
modifier letter low macron U+02CD
U+0060 ` <-- modifier letter grave accent U+02CB
U+007C | <-- divides U+2223
U+007E ~ <-- tilde operator U+223C
```

View file

@ -1,773 +0,0 @@
/* -*- mode: c; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil -*- */
/*
* Copyright (c) 2014-2019 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contributors.
* Copyright (c) 2009 Public Software Group e. V., Berlin, Germany
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* This library contains derived data from a modified version of the
* Unicode data files.
*
* The original data files are available at
* http://www.unicode.org/Public/UNIDATA/
*
* Please notice the copyright statement in the file "utf8proc_data.c".
*/
/*
* File name: utf8proc.c
*
* Description:
* Implementation of libutf8proc.
*/
#include "utf8proc.h"
#ifndef SSIZE_MAX
#define SSIZE_MAX ((size_t)SIZE_MAX/2)
#endif
#ifndef UINT16_MAX
# define UINT16_MAX 65535U
#endif
#include "utf8proc_data.c"
UTF8PROC_DLLEXPORT const utf8proc_int8_t utf8proc_utf8class[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 };
#define UTF8PROC_HANGUL_SBASE 0xAC00
#define UTF8PROC_HANGUL_LBASE 0x1100
#define UTF8PROC_HANGUL_VBASE 0x1161
#define UTF8PROC_HANGUL_TBASE 0x11A7
#define UTF8PROC_HANGUL_LCOUNT 19
#define UTF8PROC_HANGUL_VCOUNT 21
#define UTF8PROC_HANGUL_TCOUNT 28
#define UTF8PROC_HANGUL_NCOUNT 588
#define UTF8PROC_HANGUL_SCOUNT 11172
/* END is exclusive */
#define UTF8PROC_HANGUL_L_START 0x1100
#define UTF8PROC_HANGUL_L_END 0x115A
#define UTF8PROC_HANGUL_L_FILLER 0x115F
#define UTF8PROC_HANGUL_V_START 0x1160
#define UTF8PROC_HANGUL_V_END 0x11A3
#define UTF8PROC_HANGUL_T_START 0x11A8
#define UTF8PROC_HANGUL_T_END 0x11FA
#define UTF8PROC_HANGUL_S_START 0xAC00
#define UTF8PROC_HANGUL_S_END 0xD7A4
/* Should follow semantic-versioning rules (semver.org) based on API
compatibility. (Note that the shared-library version number will
be different, being based on ABI compatibility.): */
#define STRINGIZEx(x) #x
#define STRINGIZE(x) STRINGIZEx(x)
UTF8PROC_DLLEXPORT const char *utf8proc_version(void) {
return STRINGIZE(UTF8PROC_VERSION_MAJOR) "." STRINGIZE(UTF8PROC_VERSION_MINOR) "." STRINGIZE(UTF8PROC_VERSION_PATCH) "";
}
UTF8PROC_DLLEXPORT const char *utf8proc_unicode_version(void) {
return "12.1.0";
}
UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode) {
switch (errcode) {
case UTF8PROC_ERROR_NOMEM:
return "Memory for processing UTF-8 data could not be allocated.";
case UTF8PROC_ERROR_OVERFLOW:
return "UTF-8 string is too long to be processed.";
case UTF8PROC_ERROR_INVALIDUTF8:
return "Invalid UTF-8 string";
case UTF8PROC_ERROR_NOTASSIGNED:
return "Unassigned Unicode code point found in UTF-8 string.";
case UTF8PROC_ERROR_INVALIDOPTS:
return "Invalid options for UTF-8 processing chosen.";
default:
return "An unknown error occurred while processing UTF-8 data.";
}
}
#define utf_cont(ch) (((ch) & 0xc0) == 0x80)
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_int32_t *dst
) {
utf8proc_uint32_t uc;
const utf8proc_uint8_t *end;
*dst = -1;
if (!strlen) return 0;
end = str + ((strlen < 0) ? 4 : strlen);
uc = *str++;
if (uc < 0x80) {
*dst = uc;
return 1;
}
// Must be between 0xc2 and 0xf4 inclusive to be valid
if ((uc - 0xc2) > (0xf4-0xc2)) return UTF8PROC_ERROR_INVALIDUTF8;
if (uc < 0xe0) { // 2-byte sequence
// Must have valid continuation character
if (str >= end || !utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8;
*dst = ((uc & 0x1f)<<6) | (*str & 0x3f);
return 2;
}
if (uc < 0xf0) { // 3-byte sequence
if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1]))
return UTF8PROC_ERROR_INVALIDUTF8;
// Check for surrogate chars
if (uc == 0xed && *str > 0x9f)
return UTF8PROC_ERROR_INVALIDUTF8;
uc = ((uc & 0xf)<<12) | ((*str & 0x3f)<<6) | (str[1] & 0x3f);
if (uc < 0x800)
return UTF8PROC_ERROR_INVALIDUTF8;
*dst = uc;
return 3;
}
// 4-byte sequence
// Must have 3 valid continuation characters
if ((str + 2 >= end) || !utf_cont(*str) || !utf_cont(str[1]) || !utf_cont(str[2]))
return UTF8PROC_ERROR_INVALIDUTF8;
// Make sure in correct range (0x10000 - 0x10ffff)
if (uc == 0xf0) {
if (*str < 0x90) return UTF8PROC_ERROR_INVALIDUTF8;
} else if (uc == 0xf4) {
if (*str > 0x8f) return UTF8PROC_ERROR_INVALIDUTF8;
}
*dst = ((uc & 7)<<18) | ((*str & 0x3f)<<12) | ((str[1] & 0x3f)<<6) | (str[2] & 0x3f);
return 4;
}
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t uc) {
return (((utf8proc_uint32_t)uc)-0xd800 > 0x07ff) && ((utf8proc_uint32_t)uc < 0x110000);
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t uc, utf8proc_uint8_t *dst) {
if (uc < 0x00) {
return 0;
} else if (uc < 0x80) {
dst[0] = (utf8proc_uint8_t) uc;
return 1;
} else if (uc < 0x800) {
dst[0] = (utf8proc_uint8_t)(0xC0 + (uc >> 6));
dst[1] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
return 2;
// Note: we allow encoding 0xd800-0xdfff here, so as not to change
// the API, however, these are actually invalid in UTF-8
} else if (uc < 0x10000) {
dst[0] = (utf8proc_uint8_t)(0xE0 + (uc >> 12));
dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
dst[2] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
return 3;
} else if (uc < 0x110000) {
dst[0] = (utf8proc_uint8_t)(0xF0 + (uc >> 18));
dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 12) & 0x3F));
dst[2] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
dst[3] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
return 4;
} else return 0;
}
/* internal version used for inserting 0xff bytes between graphemes */
static utf8proc_ssize_t charbound_encode_char(utf8proc_int32_t uc, utf8proc_uint8_t *dst) {
if (uc < 0x00) {
if (uc == -1) { /* internal value used for grapheme breaks */
dst[0] = (utf8proc_uint8_t)0xFF;
return 1;
}
return 0;
} else if (uc < 0x80) {
dst[0] = (utf8proc_uint8_t)uc;
return 1;
} else if (uc < 0x800) {
dst[0] = (utf8proc_uint8_t)(0xC0 + (uc >> 6));
dst[1] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
return 2;
} else if (uc < 0x10000) {
dst[0] = (utf8proc_uint8_t)(0xE0 + (uc >> 12));
dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
dst[2] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
return 3;
} else if (uc < 0x110000) {
dst[0] = (utf8proc_uint8_t)(0xF0 + (uc >> 18));
dst[1] = (utf8proc_uint8_t)(0x80 + ((uc >> 12) & 0x3F));
dst[2] = (utf8proc_uint8_t)(0x80 + ((uc >> 6) & 0x3F));
dst[3] = (utf8proc_uint8_t)(0x80 + (uc & 0x3F));
return 4;
} else return 0;
}
/* internal "unsafe" version that does not check whether uc is in range */
static const utf8proc_property_t *unsafe_get_property(utf8proc_int32_t uc) {
/* ASSERT: uc >= 0 && uc < 0x110000 */
return utf8proc_properties + (
utf8proc_stage2table[
utf8proc_stage1table[uc >> 8] + (uc & 0xFF)
]
);
}
UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8proc_int32_t uc) {
return uc < 0 || uc >= 0x110000 ? utf8proc_properties : unsafe_get_property(uc);
}
/* return whether there is a grapheme break between boundclasses lbc and tbc
(according to the definition of extended grapheme clusters)
Rule numbering refers to TR29 Version 29 (Unicode 9.0.0):
http://www.unicode.org/reports/tr29/tr29-29.html
CAVEATS:
Please note that evaluation of GB10 (grapheme breaks between emoji zwj sequences)
and GB 12/13 (regional indicator code points) require knowledge of previous characters
and are thus not handled by this function. This may result in an incorrect break before
an E_Modifier class codepoint and an incorrectly missing break between two
REGIONAL_INDICATOR class code points if such support does not exist in the caller.
See the special support in grapheme_break_extended, for required bookkeeping by the caller.
*/
static utf8proc_bool grapheme_break_simple(int lbc, int tbc) {
return
(lbc == UTF8PROC_BOUNDCLASS_START) ? true : // GB1
(lbc == UTF8PROC_BOUNDCLASS_CR && // GB3
tbc == UTF8PROC_BOUNDCLASS_LF) ? false : // ---
(lbc >= UTF8PROC_BOUNDCLASS_CR && lbc <= UTF8PROC_BOUNDCLASS_CONTROL) ? true : // GB4
(tbc >= UTF8PROC_BOUNDCLASS_CR && tbc <= UTF8PROC_BOUNDCLASS_CONTROL) ? true : // GB5
(lbc == UTF8PROC_BOUNDCLASS_L && // GB6
(tbc == UTF8PROC_BOUNDCLASS_L || // ---
tbc == UTF8PROC_BOUNDCLASS_V || // ---
tbc == UTF8PROC_BOUNDCLASS_LV || // ---
tbc == UTF8PROC_BOUNDCLASS_LVT)) ? false : // ---
((lbc == UTF8PROC_BOUNDCLASS_LV || // GB7
lbc == UTF8PROC_BOUNDCLASS_V) && // ---
(tbc == UTF8PROC_BOUNDCLASS_V || // ---
tbc == UTF8PROC_BOUNDCLASS_T)) ? false : // ---
((lbc == UTF8PROC_BOUNDCLASS_LVT || // GB8
lbc == UTF8PROC_BOUNDCLASS_T) && // ---
tbc == UTF8PROC_BOUNDCLASS_T) ? false : // ---
(tbc == UTF8PROC_BOUNDCLASS_EXTEND || // GB9
tbc == UTF8PROC_BOUNDCLASS_ZWJ || // ---
tbc == UTF8PROC_BOUNDCLASS_SPACINGMARK || // GB9a
lbc == UTF8PROC_BOUNDCLASS_PREPEND) ? false : // GB9b
(lbc == UTF8PROC_BOUNDCLASS_E_ZWG && // GB11 (requires additional handling below)
tbc == UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC) ? false : // ----
(lbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR && // GB12/13 (requires additional handling below)
tbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR) ? false : // ----
true; // GB999
}
static utf8proc_bool grapheme_break_extended(int lbc, int tbc, utf8proc_int32_t *state)
{
int lbc_override = ((state && *state != UTF8PROC_BOUNDCLASS_START)
? *state : lbc);
utf8proc_bool break_permitted = grapheme_break_simple(lbc_override, tbc);
if (state) {
// Special support for GB 12/13 made possible by GB999. After two RI
// class codepoints we want to force a break. Do this by resetting the
// second RI's bound class to UTF8PROC_BOUNDCLASS_OTHER, to force a break
// after that character according to GB999 (unless of course such a break is
// forbidden by a different rule such as GB9).
if (*state == tbc && tbc == UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR)
*state = UTF8PROC_BOUNDCLASS_OTHER;
// Special support for GB11 (emoji extend* zwj / emoji)
else if (*state == UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC) {
if (tbc == UTF8PROC_BOUNDCLASS_EXTEND) // fold EXTEND codepoints into emoji
*state = UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC;
else if (tbc == UTF8PROC_BOUNDCLASS_ZWJ)
*state = UTF8PROC_BOUNDCLASS_E_ZWG; // state to record emoji+zwg combo
else
*state = tbc;
}
else
*state = tbc;
}
return break_permitted;
}
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful(
utf8proc_int32_t c1, utf8proc_int32_t c2, utf8proc_int32_t *state) {
return grapheme_break_extended(utf8proc_get_property(c1)->boundclass,
utf8proc_get_property(c2)->boundclass,
state);
}
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break(
utf8proc_int32_t c1, utf8proc_int32_t c2) {
return utf8proc_grapheme_break_stateful(c1, c2, NULL);
}
static utf8proc_int32_t seqindex_decode_entry(const utf8proc_uint16_t **entry)
{
utf8proc_int32_t entry_cp = **entry;
if ((entry_cp & 0xF800) == 0xD800) {
*entry = *entry + 1;
entry_cp = ((entry_cp & 0x03FF) << 10) | (**entry & 0x03FF);
entry_cp += 0x10000;
}
return entry_cp;
}
static utf8proc_int32_t seqindex_decode_index(const utf8proc_uint32_t seqindex)
{
const utf8proc_uint16_t *entry = &utf8proc_sequences[seqindex];
return seqindex_decode_entry(&entry);
}
static utf8proc_ssize_t seqindex_write_char_decomposed(utf8proc_uint16_t seqindex, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, utf8proc_option_t options, int *last_boundclass) {
utf8proc_ssize_t written = 0;
const utf8proc_uint16_t *entry = &utf8proc_sequences[seqindex & 0x1FFF];
int len = seqindex >> 13;
if (len >= 7) {
len = *entry;
entry++;
}
for (; len >= 0; entry++, len--) {
utf8proc_int32_t entry_cp = seqindex_decode_entry(&entry);
written += utf8proc_decompose_char(entry_cp, dst+written,
(bufsize > written) ? (bufsize - written) : 0, options,
last_boundclass);
if (written < 0) return UTF8PROC_ERROR_OVERFLOW;
}
return written;
}
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c)
{
utf8proc_int32_t cl = utf8proc_get_property(c)->lowercase_seqindex;
return cl != UINT16_MAX ? seqindex_decode_index(cl) : c;
}
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c)
{
utf8proc_int32_t cu = utf8proc_get_property(c)->uppercase_seqindex;
return cu != UINT16_MAX ? seqindex_decode_index(cu) : c;
}
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c)
{
utf8proc_int32_t cu = utf8proc_get_property(c)->titlecase_seqindex;
return cu != UINT16_MAX ? seqindex_decode_index(cu) : c;
}
/* return a character width analogous to wcwidth (except portable and
hopefully less buggy than most system wcwidth functions). */
UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t c) {
return utf8proc_get_property(c)->charwidth;
}
UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t c) {
return utf8proc_get_property(c)->category;
}
UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t c) {
static const char s[][3] = {"Cn","Lu","Ll","Lt","Lm","Lo","Mn","Mc","Me","Nd","Nl","No","Pc","Pd","Ps","Pe","Pi","Pf","Po","Sm","Sc","Sk","So","Zs","Zl","Zp","Cc","Cf","Cs","Co"};
return s[utf8proc_category(c)];
}
#define utf8proc_decompose_lump(replacement_uc) \
return utf8proc_decompose_char((replacement_uc), dst, bufsize, \
options & ~UTF8PROC_LUMP, last_boundclass)
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(utf8proc_int32_t uc, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize, utf8proc_option_t options, int *last_boundclass) {
const utf8proc_property_t *property;
utf8proc_propval_t category;
utf8proc_int32_t hangul_sindex;
if (uc < 0 || uc >= 0x110000) return UTF8PROC_ERROR_NOTASSIGNED;
property = unsafe_get_property(uc);
category = property->category;
hangul_sindex = uc - UTF8PROC_HANGUL_SBASE;
if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) {
if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT) {
utf8proc_int32_t hangul_tindex;
if (bufsize >= 1) {
dst[0] = UTF8PROC_HANGUL_LBASE +
hangul_sindex / UTF8PROC_HANGUL_NCOUNT;
if (bufsize >= 2) dst[1] = UTF8PROC_HANGUL_VBASE +
(hangul_sindex % UTF8PROC_HANGUL_NCOUNT) / UTF8PROC_HANGUL_TCOUNT;
}
hangul_tindex = hangul_sindex % UTF8PROC_HANGUL_TCOUNT;
if (!hangul_tindex) return 2;
if (bufsize >= 3) dst[2] = UTF8PROC_HANGUL_TBASE + hangul_tindex;
return 3;
}
}
if (options & UTF8PROC_REJECTNA) {
if (!category) return UTF8PROC_ERROR_NOTASSIGNED;
}
if (options & UTF8PROC_IGNORE) {
if (property->ignorable) return 0;
}
if (options & UTF8PROC_STRIPNA) {
if (!category) return 0;
}
if (options & UTF8PROC_LUMP) {
if (category == UTF8PROC_CATEGORY_ZS) utf8proc_decompose_lump(0x0020);
if (uc == 0x2018 || uc == 0x2019 || uc == 0x02BC || uc == 0x02C8)
utf8proc_decompose_lump(0x0027);
if (category == UTF8PROC_CATEGORY_PD || uc == 0x2212)
utf8proc_decompose_lump(0x002D);
if (uc == 0x2044 || uc == 0x2215) utf8proc_decompose_lump(0x002F);
if (uc == 0x2236) utf8proc_decompose_lump(0x003A);
if (uc == 0x2039 || uc == 0x2329 || uc == 0x3008)
utf8proc_decompose_lump(0x003C);
if (uc == 0x203A || uc == 0x232A || uc == 0x3009)
utf8proc_decompose_lump(0x003E);
if (uc == 0x2216) utf8proc_decompose_lump(0x005C);
if (uc == 0x02C4 || uc == 0x02C6 || uc == 0x2038 || uc == 0x2303)
utf8proc_decompose_lump(0x005E);
if (category == UTF8PROC_CATEGORY_PC || uc == 0x02CD)
utf8proc_decompose_lump(0x005F);
if (uc == 0x02CB) utf8proc_decompose_lump(0x0060);
if (uc == 0x2223) utf8proc_decompose_lump(0x007C);
if (uc == 0x223C) utf8proc_decompose_lump(0x007E);
if ((options & UTF8PROC_NLF2LS) && (options & UTF8PROC_NLF2PS)) {
if (category == UTF8PROC_CATEGORY_ZL ||
category == UTF8PROC_CATEGORY_ZP)
utf8proc_decompose_lump(0x000A);
}
}
if (options & UTF8PROC_STRIPMARK) {
if (category == UTF8PROC_CATEGORY_MN ||
category == UTF8PROC_CATEGORY_MC ||
category == UTF8PROC_CATEGORY_ME) return 0;
}
if (options & UTF8PROC_CASEFOLD) {
if (property->casefold_seqindex != UINT16_MAX) {
return seqindex_write_char_decomposed(property->casefold_seqindex, dst, bufsize, options, last_boundclass);
}
}
if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) {
if (property->decomp_seqindex != UINT16_MAX &&
(!property->decomp_type || (options & UTF8PROC_COMPAT))) {
return seqindex_write_char_decomposed(property->decomp_seqindex, dst, bufsize, options, last_boundclass);
}
}
if (options & UTF8PROC_CHARBOUND) {
utf8proc_bool boundary;
int tbc = property->boundclass;
boundary = grapheme_break_extended(*last_boundclass, tbc, last_boundclass);
if (boundary) {
if (bufsize >= 1) dst[0] = -1; /* sentinel value for grapheme break */
if (bufsize >= 2) dst[1] = uc;
return 2;
}
}
if (bufsize >= 1) *dst = uc;
return 1;
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options
) {
return utf8proc_decompose_custom(str, strlen, buffer, bufsize, options, NULL, NULL);
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options,
utf8proc_custom_func custom_func, void *custom_data
) {
/* strlen will be ignored, if UTF8PROC_NULLTERM is set in options */
utf8proc_ssize_t wpos = 0;
if ((options & UTF8PROC_COMPOSE) && (options & UTF8PROC_DECOMPOSE))
return UTF8PROC_ERROR_INVALIDOPTS;
if ((options & UTF8PROC_STRIPMARK) &&
!(options & UTF8PROC_COMPOSE) && !(options & UTF8PROC_DECOMPOSE))
return UTF8PROC_ERROR_INVALIDOPTS;
{
utf8proc_int32_t uc;
utf8proc_ssize_t rpos = 0;
utf8proc_ssize_t decomp_result;
int boundclass = UTF8PROC_BOUNDCLASS_START;
while (1) {
if (options & UTF8PROC_NULLTERM) {
rpos += utf8proc_iterate(str + rpos, -1, &uc);
/* checking of return value is not necessary,
as 'uc' is < 0 in case of error */
if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8;
if (rpos < 0) return UTF8PROC_ERROR_OVERFLOW;
if (uc == 0) break;
} else {
if (rpos >= strlen) break;
rpos += utf8proc_iterate(str + rpos, strlen - rpos, &uc);
if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8;
}
if (custom_func != NULL) {
uc = custom_func(uc, custom_data); /* user-specified custom mapping */
}
decomp_result = utf8proc_decompose_char(
uc, buffer + wpos, (bufsize > wpos) ? (bufsize - wpos) : 0, options,
&boundclass
);
if (decomp_result < 0) return decomp_result;
wpos += decomp_result;
/* prohibiting integer overflows due to too long strings: */
if (wpos < 0 ||
wpos > (utf8proc_ssize_t)(SSIZE_MAX/sizeof(utf8proc_int32_t)/2))
return UTF8PROC_ERROR_OVERFLOW;
}
}
if ((options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) && bufsize >= wpos) {
utf8proc_ssize_t pos = 0;
while (pos < wpos-1) {
utf8proc_int32_t uc1, uc2;
const utf8proc_property_t *property1, *property2;
uc1 = buffer[pos];
uc2 = buffer[pos+1];
property1 = unsafe_get_property(uc1);
property2 = unsafe_get_property(uc2);
if (property1->combining_class > property2->combining_class &&
property2->combining_class > 0) {
buffer[pos] = uc2;
buffer[pos+1] = uc1;
if (pos > 0) pos--; else pos++;
} else {
pos++;
}
}
}
return wpos;
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options) {
/* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored */
if (options & (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS | UTF8PROC_STRIPCC)) {
utf8proc_ssize_t rpos;
utf8proc_ssize_t wpos = 0;
utf8proc_int32_t uc;
for (rpos = 0; rpos < length; rpos++) {
uc = buffer[rpos];
if (uc == 0x000D && rpos < length-1 && buffer[rpos+1] == 0x000A) rpos++;
if (uc == 0x000A || uc == 0x000D || uc == 0x0085 ||
((options & UTF8PROC_STRIPCC) && (uc == 0x000B || uc == 0x000C))) {
if (options & UTF8PROC_NLF2LS) {
if (options & UTF8PROC_NLF2PS) {
buffer[wpos++] = 0x000A;
} else {
buffer[wpos++] = 0x2028;
}
} else {
if (options & UTF8PROC_NLF2PS) {
buffer[wpos++] = 0x2029;
} else {
buffer[wpos++] = 0x0020;
}
}
} else if ((options & UTF8PROC_STRIPCC) &&
(uc < 0x0020 || (uc >= 0x007F && uc < 0x00A0))) {
if (uc == 0x0009) buffer[wpos++] = 0x0020;
} else {
buffer[wpos++] = uc;
}
}
length = wpos;
}
if (options & UTF8PROC_COMPOSE) {
utf8proc_int32_t *starter = NULL;
utf8proc_int32_t current_char;
const utf8proc_property_t *starter_property = NULL, *current_property;
utf8proc_propval_t max_combining_class = -1;
utf8proc_ssize_t rpos;
utf8proc_ssize_t wpos = 0;
utf8proc_int32_t composition;
for (rpos = 0; rpos < length; rpos++) {
current_char = buffer[rpos];
current_property = unsafe_get_property(current_char);
if (starter && current_property->combining_class > max_combining_class) {
/* combination perhaps possible */
utf8proc_int32_t hangul_lindex;
utf8proc_int32_t hangul_sindex;
hangul_lindex = *starter - UTF8PROC_HANGUL_LBASE;
if (hangul_lindex >= 0 && hangul_lindex < UTF8PROC_HANGUL_LCOUNT) {
utf8proc_int32_t hangul_vindex;
hangul_vindex = current_char - UTF8PROC_HANGUL_VBASE;
if (hangul_vindex >= 0 && hangul_vindex < UTF8PROC_HANGUL_VCOUNT) {
*starter = UTF8PROC_HANGUL_SBASE +
(hangul_lindex * UTF8PROC_HANGUL_VCOUNT + hangul_vindex) *
UTF8PROC_HANGUL_TCOUNT;
starter_property = NULL;
continue;
}
}
hangul_sindex = *starter - UTF8PROC_HANGUL_SBASE;
if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT &&
(hangul_sindex % UTF8PROC_HANGUL_TCOUNT) == 0) {
utf8proc_int32_t hangul_tindex;
hangul_tindex = current_char - UTF8PROC_HANGUL_TBASE;
if (hangul_tindex >= 0 && hangul_tindex < UTF8PROC_HANGUL_TCOUNT) {
*starter += hangul_tindex;
starter_property = NULL;
continue;
}
}
if (!starter_property) {
starter_property = unsafe_get_property(*starter);
}
if (starter_property->comb_index < 0x8000 &&
current_property->comb_index != UINT16_MAX &&
current_property->comb_index >= 0x8000) {
int sidx = starter_property->comb_index;
int idx = current_property->comb_index & 0x3FFF;
if (idx >= utf8proc_combinations[sidx] && idx <= utf8proc_combinations[sidx + 1] ) {
idx += sidx + 2 - utf8proc_combinations[sidx];
if (current_property->comb_index & 0x4000) {
composition = (utf8proc_combinations[idx] << 16) | utf8proc_combinations[idx+1];
} else
composition = utf8proc_combinations[idx];
if (composition > 0 && (!(options & UTF8PROC_STABLE) ||
!(unsafe_get_property(composition)->comp_exclusion))) {
*starter = composition;
starter_property = NULL;
continue;
}
}
}
}
buffer[wpos] = current_char;
if (current_property->combining_class) {
if (current_property->combining_class > max_combining_class) {
max_combining_class = current_property->combining_class;
}
} else {
starter = buffer + wpos;
starter_property = NULL;
max_combining_class = -1;
}
wpos++;
}
length = wpos;
}
return length;
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options) {
/* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored
ASSERT: 'buffer' has one spare byte of free space at the end! */
length = utf8proc_normalize_utf32(buffer, length, options);
if (length < 0) return length;
{
utf8proc_ssize_t rpos, wpos = 0;
utf8proc_int32_t uc;
if (options & UTF8PROC_CHARBOUND) {
for (rpos = 0; rpos < length; rpos++) {
uc = buffer[rpos];
wpos += charbound_encode_char(uc, ((utf8proc_uint8_t *)buffer) + wpos);
}
} else {
for (rpos = 0; rpos < length; rpos++) {
uc = buffer[rpos];
wpos += utf8proc_encode_char(uc, ((utf8proc_uint8_t *)buffer) + wpos);
}
}
((utf8proc_uint8_t *)buffer)[wpos] = 0;
return wpos;
}
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options
) {
return utf8proc_map_custom(str, strlen, dstptr, options, NULL, NULL);
}
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options,
utf8proc_custom_func custom_func, void *custom_data
) {
utf8proc_int32_t *buffer;
utf8proc_ssize_t result;
*dstptr = NULL;
result = utf8proc_decompose_custom(str, strlen, NULL, 0, options, custom_func, custom_data);
if (result < 0) return result;
buffer = (utf8proc_int32_t *) malloc(result * sizeof(utf8proc_int32_t) + 1);
if (!buffer) return UTF8PROC_ERROR_NOMEM;
result = utf8proc_decompose_custom(str, strlen, buffer, result, options, custom_func, custom_data);
if (result < 0) {
free(buffer);
return result;
}
result = utf8proc_reencode(buffer, result, options);
if (result < 0) {
free(buffer);
return result;
}
{
utf8proc_int32_t *newptr;
newptr = (utf8proc_int32_t *) realloc(buffer, (size_t)result+1);
if (newptr) buffer = newptr;
}
*dstptr = (utf8proc_uint8_t *)buffer;
return result;
}
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str) {
utf8proc_uint8_t *retval;
utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
UTF8PROC_DECOMPOSE);
return retval;
}
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str) {
utf8proc_uint8_t *retval;
utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
UTF8PROC_COMPOSE);
return retval;
}
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str) {
utf8proc_uint8_t *retval;
utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT);
return retval;
}
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str) {
utf8proc_uint8_t *retval;
utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
UTF8PROC_COMPOSE | UTF8PROC_COMPAT);
return retval;
}
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8_t *str) {
utf8proc_uint8_t *retval;
utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
UTF8PROC_COMPOSE | UTF8PROC_COMPAT | UTF8PROC_CASEFOLD | UTF8PROC_IGNORE);
return retval;
}

View file

@ -1,721 +0,0 @@
/*
* Copyright (c) 2014-2019 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony Kelman, Scott P. Jones, and other contributors.
* Copyright (c) 2009 Public Software Group e. V., Berlin, Germany
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* @mainpage
*
* utf8proc is a free/open-source (MIT/expat licensed) C library
* providing Unicode normalization, case-folding, and other operations
* for strings in the UTF-8 encoding, supporting up-to-date Unicode versions.
* See the utf8proc home page (http://julialang.org/utf8proc/)
* for downloads and other information, or the source code on github
* (https://github.com/JuliaLang/utf8proc).
*
* For the utf8proc API documentation, see: @ref utf8proc.h
*
* The features of utf8proc include:
*
* - Transformation of strings (@ref utf8proc_map) to:
* - decompose (@ref UTF8PROC_DECOMPOSE) or compose (@ref UTF8PROC_COMPOSE) Unicode combining characters (http://en.wikipedia.org/wiki/Combining_character)
* - canonicalize Unicode compatibility characters (@ref UTF8PROC_COMPAT)
* - strip "ignorable" (@ref UTF8PROC_IGNORE) characters, control characters (@ref UTF8PROC_STRIPCC), or combining characters such as accents (@ref UTF8PROC_STRIPMARK)
* - case-folding (@ref UTF8PROC_CASEFOLD)
* - Unicode normalization: @ref utf8proc_NFD, @ref utf8proc_NFC, @ref utf8proc_NFKD, @ref utf8proc_NFKC
* - Detecting grapheme boundaries (@ref utf8proc_grapheme_break and @ref UTF8PROC_CHARBOUND)
* - Character-width computation: @ref utf8proc_charwidth
* - Classification of characters by Unicode category: @ref utf8proc_category and @ref utf8proc_category_string
* - Encode (@ref utf8proc_encode_char) and decode (@ref utf8proc_iterate) Unicode codepoints to/from UTF-8.
*/
/** @file */
#ifndef UTF8PROC_H
#define UTF8PROC_H
/** @name API version
*
* The utf8proc API version MAJOR.MINOR.PATCH, following
* semantic-versioning rules (http://semver.org) based on API
* compatibility.
*
* This is also returned at runtime by @ref utf8proc_version; however, the
* runtime version may append a string like "-dev" to the version number
* for prerelease versions.
*
* @note The shared-library version number in the Makefile
* (and CMakeLists.txt, and MANIFEST) may be different,
* being based on ABI compatibility rather than API compatibility.
*/
/** @{ */
/** The MAJOR version number (increased when backwards API compatibility is broken). */
#define UTF8PROC_VERSION_MAJOR 2
/** The MINOR version number (increased when new functionality is added in a backwards-compatible manner). */
#define UTF8PROC_VERSION_MINOR 4
/** The PATCH version (increased for fixes that do not change the API). */
#define UTF8PROC_VERSION_PATCH 0
/** @} */
#include <stdlib.h>
#if defined(_MSC_VER) && _MSC_VER < 1800
// MSVC prior to 2013 lacked stdbool.h and inttypes.h
typedef signed char utf8proc_int8_t;
typedef unsigned char utf8proc_uint8_t;
typedef short utf8proc_int16_t;
typedef unsigned short utf8proc_uint16_t;
typedef int utf8proc_int32_t;
typedef unsigned int utf8proc_uint32_t;
# ifdef _WIN64
typedef __int64 utf8proc_ssize_t;
typedef unsigned __int64 utf8proc_size_t;
# else
typedef int utf8proc_ssize_t;
typedef unsigned int utf8proc_size_t;
# endif
# ifndef __cplusplus
// emulate C99 bool
typedef unsigned char utf8proc_bool;
# ifndef __bool_true_false_are_defined
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
# endif
# else
typedef bool utf8proc_bool;
# endif
#else
# include <stddef.h>
# include <stdbool.h>
# include <inttypes.h>
typedef int8_t utf8proc_int8_t;
typedef uint8_t utf8proc_uint8_t;
typedef int16_t utf8proc_int16_t;
typedef uint16_t utf8proc_uint16_t;
typedef int32_t utf8proc_int32_t;
typedef uint32_t utf8proc_uint32_t;
typedef size_t utf8proc_size_t;
typedef ptrdiff_t utf8proc_ssize_t;
typedef bool utf8proc_bool;
#endif
#include <limits.h>
#ifdef UTF8PROC_STATIC
# define UTF8PROC_DLLEXPORT
#else
# ifdef _WIN32
# ifdef UTF8PROC_EXPORTS
# define UTF8PROC_DLLEXPORT __declspec(dllexport)
# else
# define UTF8PROC_DLLEXPORT __declspec(dllimport)
# endif
# elif __GNUC__ >= 4
# define UTF8PROC_DLLEXPORT __attribute__ ((visibility("default")))
# else
# define UTF8PROC_DLLEXPORT
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* Option flags used by several functions in the library.
*/
typedef enum {
/** The given UTF-8 input is NULL terminated. */
UTF8PROC_NULLTERM = (1<<0),
/** Unicode Versioning Stability has to be respected. */
UTF8PROC_STABLE = (1<<1),
/** Compatibility decomposition (i.e. formatting information is lost). */
UTF8PROC_COMPAT = (1<<2),
/** Return a result with decomposed characters. */
UTF8PROC_COMPOSE = (1<<3),
/** Return a result with decomposed characters. */
UTF8PROC_DECOMPOSE = (1<<4),
/** Strip "default ignorable characters" such as SOFT-HYPHEN or ZERO-WIDTH-SPACE. */
UTF8PROC_IGNORE = (1<<5),
/** Return an error, if the input contains unassigned codepoints. */
UTF8PROC_REJECTNA = (1<<6),
/**
* Indicating that NLF-sequences (LF, CRLF, CR, NEL) are representing a
* line break, and should be converted to the codepoint for line
* separation (LS).
*/
UTF8PROC_NLF2LS = (1<<7),
/**
* Indicating that NLF-sequences are representing a paragraph break, and
* should be converted to the codepoint for paragraph separation
* (PS).
*/
UTF8PROC_NLF2PS = (1<<8),
/** Indicating that the meaning of NLF-sequences is unknown. */
UTF8PROC_NLF2LF = (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS),
/** Strips and/or convers control characters.
*
* NLF-sequences are transformed into space, except if one of the
* NLF2LS/PS/LF options is given. HorizontalTab (HT) and FormFeed (FF)
* are treated as a NLF-sequence in this case. All other control
* characters are simply removed.
*/
UTF8PROC_STRIPCC = (1<<9),
/**
* Performs unicode case folding, to be able to do a case-insensitive
* string comparison.
*/
UTF8PROC_CASEFOLD = (1<<10),
/**
* Inserts 0xFF bytes at the beginning of each sequence which is
* representing a single grapheme cluster (see UAX#29).
*/
UTF8PROC_CHARBOUND = (1<<11),
/** Lumps certain characters together.
*
* E.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-". See lump.md for details.
*
* If NLF2LF is set, this includes a transformation of paragraph and
* line separators to ASCII line-feed (LF).
*/
UTF8PROC_LUMP = (1<<12),
/** Strips all character markings.
*
* This includes non-spacing, spacing and enclosing (i.e. accents).
* @note This option works only with @ref UTF8PROC_COMPOSE or
* @ref UTF8PROC_DECOMPOSE
*/
UTF8PROC_STRIPMARK = (1<<13),
/**
* Strip unassigned codepoints.
*/
UTF8PROC_STRIPNA = (1<<14),
} utf8proc_option_t;
/** @name Error codes
* Error codes being returned by almost all functions.
*/
/** @{ */
/** Memory could not be allocated. */
#define UTF8PROC_ERROR_NOMEM -1
/** The given string is too long to be processed. */
#define UTF8PROC_ERROR_OVERFLOW -2
/** The given string is not a legal UTF-8 string. */
#define UTF8PROC_ERROR_INVALIDUTF8 -3
/** The @ref UTF8PROC_REJECTNA flag was set and an unassigned codepoint was found. */
#define UTF8PROC_ERROR_NOTASSIGNED -4
/** Invalid options have been used. */
#define UTF8PROC_ERROR_INVALIDOPTS -5
/** @} */
/* @name Types */
/** Holds the value of a property. */
typedef utf8proc_int16_t utf8proc_propval_t;
/** Struct containing information about a codepoint. */
typedef struct utf8proc_property_struct {
/**
* Unicode category.
* @see utf8proc_category_t.
*/
utf8proc_propval_t category;
utf8proc_propval_t combining_class;
/**
* Bidirectional class.
* @see utf8proc_bidi_class_t.
*/
utf8proc_propval_t bidi_class;
/**
* @anchor Decomposition type.
* @see utf8proc_decomp_type_t.
*/
utf8proc_propval_t decomp_type;
utf8proc_uint16_t decomp_seqindex;
utf8proc_uint16_t casefold_seqindex;
utf8proc_uint16_t uppercase_seqindex;
utf8proc_uint16_t lowercase_seqindex;
utf8proc_uint16_t titlecase_seqindex;
utf8proc_uint16_t comb_index;
unsigned bidi_mirrored:1;
unsigned comp_exclusion:1;
/**
* Can this codepoint be ignored?
*
* Used by @ref utf8proc_decompose_char when @ref UTF8PROC_IGNORE is
* passed as an option.
*/
unsigned ignorable:1;
unsigned control_boundary:1;
/** The width of the codepoint. */
unsigned charwidth:2;
unsigned pad:2;
/**
* Boundclass.
* @see utf8proc_boundclass_t.
*/
unsigned boundclass:8;
} utf8proc_property_t;
/** Unicode categories. */
typedef enum {
UTF8PROC_CATEGORY_CN = 0, /**< Other, not assigned */
UTF8PROC_CATEGORY_LU = 1, /**< Letter, uppercase */
UTF8PROC_CATEGORY_LL = 2, /**< Letter, lowercase */
UTF8PROC_CATEGORY_LT = 3, /**< Letter, titlecase */
UTF8PROC_CATEGORY_LM = 4, /**< Letter, modifier */
UTF8PROC_CATEGORY_LO = 5, /**< Letter, other */
UTF8PROC_CATEGORY_MN = 6, /**< Mark, nonspacing */
UTF8PROC_CATEGORY_MC = 7, /**< Mark, spacing combining */
UTF8PROC_CATEGORY_ME = 8, /**< Mark, enclosing */
UTF8PROC_CATEGORY_ND = 9, /**< Number, decimal digit */
UTF8PROC_CATEGORY_NL = 10, /**< Number, letter */
UTF8PROC_CATEGORY_NO = 11, /**< Number, other */
UTF8PROC_CATEGORY_PC = 12, /**< Punctuation, connector */
UTF8PROC_CATEGORY_PD = 13, /**< Punctuation, dash */
UTF8PROC_CATEGORY_PS = 14, /**< Punctuation, open */
UTF8PROC_CATEGORY_PE = 15, /**< Punctuation, close */
UTF8PROC_CATEGORY_PI = 16, /**< Punctuation, initial quote */
UTF8PROC_CATEGORY_PF = 17, /**< Punctuation, final quote */
UTF8PROC_CATEGORY_PO = 18, /**< Punctuation, other */
UTF8PROC_CATEGORY_SM = 19, /**< Symbol, math */
UTF8PROC_CATEGORY_SC = 20, /**< Symbol, currency */
UTF8PROC_CATEGORY_SK = 21, /**< Symbol, modifier */
UTF8PROC_CATEGORY_SO = 22, /**< Symbol, other */
UTF8PROC_CATEGORY_ZS = 23, /**< Separator, space */
UTF8PROC_CATEGORY_ZL = 24, /**< Separator, line */
UTF8PROC_CATEGORY_ZP = 25, /**< Separator, paragraph */
UTF8PROC_CATEGORY_CC = 26, /**< Other, control */
UTF8PROC_CATEGORY_CF = 27, /**< Other, format */
UTF8PROC_CATEGORY_CS = 28, /**< Other, surrogate */
UTF8PROC_CATEGORY_CO = 29, /**< Other, private use */
} utf8proc_category_t;
/** Bidirectional character classes. */
typedef enum {
UTF8PROC_BIDI_CLASS_L = 1, /**< Left-to-Right */
UTF8PROC_BIDI_CLASS_LRE = 2, /**< Left-to-Right Embedding */
UTF8PROC_BIDI_CLASS_LRO = 3, /**< Left-to-Right Override */
UTF8PROC_BIDI_CLASS_R = 4, /**< Right-to-Left */
UTF8PROC_BIDI_CLASS_AL = 5, /**< Right-to-Left Arabic */
UTF8PROC_BIDI_CLASS_RLE = 6, /**< Right-to-Left Embedding */
UTF8PROC_BIDI_CLASS_RLO = 7, /**< Right-to-Left Override */
UTF8PROC_BIDI_CLASS_PDF = 8, /**< Pop Directional Format */
UTF8PROC_BIDI_CLASS_EN = 9, /**< European Number */
UTF8PROC_BIDI_CLASS_ES = 10, /**< European Separator */
UTF8PROC_BIDI_CLASS_ET = 11, /**< European Number Terminator */
UTF8PROC_BIDI_CLASS_AN = 12, /**< Arabic Number */
UTF8PROC_BIDI_CLASS_CS = 13, /**< Common Number Separator */
UTF8PROC_BIDI_CLASS_NSM = 14, /**< Nonspacing Mark */
UTF8PROC_BIDI_CLASS_BN = 15, /**< Boundary Neutral */
UTF8PROC_BIDI_CLASS_B = 16, /**< Paragraph Separator */
UTF8PROC_BIDI_CLASS_S = 17, /**< Segment Separator */
UTF8PROC_BIDI_CLASS_WS = 18, /**< Whitespace */
UTF8PROC_BIDI_CLASS_ON = 19, /**< Other Neutrals */
UTF8PROC_BIDI_CLASS_LRI = 20, /**< Left-to-Right Isolate */
UTF8PROC_BIDI_CLASS_RLI = 21, /**< Right-to-Left Isolate */
UTF8PROC_BIDI_CLASS_FSI = 22, /**< First Strong Isolate */
UTF8PROC_BIDI_CLASS_PDI = 23, /**< Pop Directional Isolate */
} utf8proc_bidi_class_t;
/** Decomposition type. */
typedef enum {
UTF8PROC_DECOMP_TYPE_FONT = 1, /**< Font */
UTF8PROC_DECOMP_TYPE_NOBREAK = 2, /**< Nobreak */
UTF8PROC_DECOMP_TYPE_INITIAL = 3, /**< Initial */
UTF8PROC_DECOMP_TYPE_MEDIAL = 4, /**< Medial */
UTF8PROC_DECOMP_TYPE_FINAL = 5, /**< Final */
UTF8PROC_DECOMP_TYPE_ISOLATED = 6, /**< Isolated */
UTF8PROC_DECOMP_TYPE_CIRCLE = 7, /**< Circle */
UTF8PROC_DECOMP_TYPE_SUPER = 8, /**< Super */
UTF8PROC_DECOMP_TYPE_SUB = 9, /**< Sub */
UTF8PROC_DECOMP_TYPE_VERTICAL = 10, /**< Vertical */
UTF8PROC_DECOMP_TYPE_WIDE = 11, /**< Wide */
UTF8PROC_DECOMP_TYPE_NARROW = 12, /**< Narrow */
UTF8PROC_DECOMP_TYPE_SMALL = 13, /**< Small */
UTF8PROC_DECOMP_TYPE_SQUARE = 14, /**< Square */
UTF8PROC_DECOMP_TYPE_FRACTION = 15, /**< Fraction */
UTF8PROC_DECOMP_TYPE_COMPAT = 16, /**< Compat */
} utf8proc_decomp_type_t;
/** Boundclass property. (TR29) */
typedef enum {
UTF8PROC_BOUNDCLASS_START = 0, /**< Start */
UTF8PROC_BOUNDCLASS_OTHER = 1, /**< Other */
UTF8PROC_BOUNDCLASS_CR = 2, /**< Cr */
UTF8PROC_BOUNDCLASS_LF = 3, /**< Lf */
UTF8PROC_BOUNDCLASS_CONTROL = 4, /**< Control */
UTF8PROC_BOUNDCLASS_EXTEND = 5, /**< Extend */
UTF8PROC_BOUNDCLASS_L = 6, /**< L */
UTF8PROC_BOUNDCLASS_V = 7, /**< V */
UTF8PROC_BOUNDCLASS_T = 8, /**< T */
UTF8PROC_BOUNDCLASS_LV = 9, /**< Lv */
UTF8PROC_BOUNDCLASS_LVT = 10, /**< Lvt */
UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR = 11, /**< Regional indicator */
UTF8PROC_BOUNDCLASS_SPACINGMARK = 12, /**< Spacingmark */
UTF8PROC_BOUNDCLASS_PREPEND = 13, /**< Prepend */
UTF8PROC_BOUNDCLASS_ZWJ = 14, /**< Zero Width Joiner */
/* the following are no longer used in Unicode 11, but we keep
the constants here for backward compatibility */
UTF8PROC_BOUNDCLASS_E_BASE = 15, /**< Emoji Base */
UTF8PROC_BOUNDCLASS_E_MODIFIER = 16, /**< Emoji Modifier */
UTF8PROC_BOUNDCLASS_GLUE_AFTER_ZWJ = 17, /**< Glue_After_ZWJ */
UTF8PROC_BOUNDCLASS_E_BASE_GAZ = 18, /**< E_BASE + GLUE_AFTER_ZJW */
/* the Extended_Pictographic property is used in the Unicode 11
grapheme-boundary rules, so we store it in the boundclass field */
UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC = 19,
UTF8PROC_BOUNDCLASS_E_ZWG = 20, /* UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC + ZWJ */
} utf8proc_boundclass_t;
/**
* Function pointer type passed to @ref utf8proc_map_custom and
* @ref utf8proc_decompose_custom, which is used to specify a user-defined
* mapping of codepoints to be applied in conjunction with other mappings.
*/
typedef utf8proc_int32_t (*utf8proc_custom_func)(utf8proc_int32_t codepoint, void *data);
/**
* Array containing the byte lengths of a UTF-8 encoded codepoint based
* on the first byte.
*/
UTF8PROC_DLLEXPORT extern const utf8proc_int8_t utf8proc_utf8class[256];
/**
* Returns the utf8proc API version as a string MAJOR.MINOR.PATCH
* (http://semver.org format), possibly with a "-dev" suffix for
* development versions.
*/
UTF8PROC_DLLEXPORT const char *utf8proc_version(void);
/**
* Returns the utf8proc supported Unicode version as a string MAJOR.MINOR.PATCH.
*/
UTF8PROC_DLLEXPORT const char *utf8proc_unicode_version(void);
/**
* Returns an informative error string for the given utf8proc error code
* (e.g. the error codes returned by @ref utf8proc_map).
*/
UTF8PROC_DLLEXPORT const char *utf8proc_errmsg(utf8proc_ssize_t errcode);
/**
* Reads a single codepoint from the UTF-8 sequence being pointed to by `str`.
* The maximum number of bytes read is `strlen`, unless `strlen` is
* negative (in which case up to 4 bytes are read).
*
* If a valid codepoint could be read, it is stored in the variable
* pointed to by `codepoint_ref`, otherwise that variable will be set to -1.
* In case of success, the number of bytes read is returned; otherwise, a
* negative error code is returned.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_int32_t *codepoint_ref);
/**
* Check if a codepoint is valid (regardless of whether it has been
* assigned a value by the current Unicode standard).
*
* @return 1 if the given `codepoint` is valid and otherwise return 0.
*/
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t codepoint);
/**
* Encodes the codepoint as an UTF-8 string in the byte array pointed
* to by `dst`. This array must be at least 4 bytes long.
*
* In case of success the number of bytes written is returned, and
* otherwise 0 is returned.
*
* This function does not check whether `codepoint` is valid Unicode.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t codepoint, utf8proc_uint8_t *dst);
/**
* Look up the properties for a given codepoint.
*
* @param codepoint The Unicode codepoint.
*
* @returns
* A pointer to a (constant) struct containing information about
* the codepoint.
* @par
* If the codepoint is unassigned or invalid, a pointer to a special struct is
* returned in which `category` is 0 (@ref UTF8PROC_CATEGORY_CN).
*/
UTF8PROC_DLLEXPORT const utf8proc_property_t *utf8proc_get_property(utf8proc_int32_t codepoint);
/** Decompose a codepoint into an array of codepoints.
*
* @param codepoint the codepoint.
* @param dst the destination buffer.
* @param bufsize the size of the destination buffer.
* @param options one or more of the following flags:
* - @ref UTF8PROC_REJECTNA - return an error `codepoint` is unassigned
* - @ref UTF8PROC_IGNORE - strip "default ignorable" codepoints
* - @ref UTF8PROC_CASEFOLD - apply Unicode casefolding
* - @ref UTF8PROC_COMPAT - replace certain codepoints with their
* compatibility decomposition
* - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster
* - @ref UTF8PROC_LUMP - lump certain different codepoints together
* - @ref UTF8PROC_STRIPMARK - remove all character marks
* - @ref UTF8PROC_STRIPNA - remove unassigned codepoints
* @param last_boundclass
* Pointer to an integer variable containing
* the previous codepoint's boundary class if the @ref UTF8PROC_CHARBOUND
* option is used. Otherwise, this parameter is ignored.
*
* @return
* In case of success, the number of codepoints written is returned; in case
* of an error, a negative error code is returned (@ref utf8proc_errmsg).
* @par
* If the number of written codepoints would be bigger than `bufsize`, the
* required buffer size is returned, while the buffer will be overwritten with
* undefined data.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(
utf8proc_int32_t codepoint, utf8proc_int32_t *dst, utf8proc_ssize_t bufsize,
utf8proc_option_t options, int *last_boundclass
);
/**
* The same as @ref utf8proc_decompose_char, but acts on a whole UTF-8
* string and orders the decomposed sequences correctly.
*
* If the @ref UTF8PROC_NULLTERM flag in `options` is set, processing
* will be stopped, when a NULL byte is encounted, otherwise `strlen`
* bytes are processed. The result (in the form of 32-bit unicode
* codepoints) is written into the buffer being pointed to by
* `buffer` (which must contain at least `bufsize` entries). In case of
* success, the number of codepoints written is returned; in case of an
* error, a negative error code is returned (@ref utf8proc_errmsg).
* See @ref utf8proc_decompose_custom to supply additional transformations.
*
* If the number of written codepoints would be bigger than `bufsize`, the
* required buffer size is returned, while the buffer will be overwritten with
* undefined data.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options
);
/**
* The same as @ref utf8proc_decompose, but also takes a `custom_func` mapping function
* that is called on each codepoint in `str` before any other transformations
* (along with a `custom_data` pointer that is passed through to `custom_func`).
* The `custom_func` argument is ignored if it is `NULL`. See also @ref utf8proc_map_custom.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen,
utf8proc_int32_t *buffer, utf8proc_ssize_t bufsize, utf8proc_option_t options,
utf8proc_custom_func custom_func, void *custom_data
);
/**
* Normalizes the sequence of `length` codepoints pointed to by `buffer`
* in-place (i.e., the result is also stored in `buffer`).
*
* @param buffer the (native-endian UTF-32) unicode codepoints to re-encode.
* @param length the length (in codepoints) of the buffer.
* @param options a bitwise or (`|`) of one or more of the following flags:
* - @ref UTF8PROC_NLF2LS - convert LF, CRLF, CR and NEL into LS
* - @ref UTF8PROC_NLF2PS - convert LF, CRLF, CR and NEL into PS
* - @ref UTF8PROC_NLF2LF - convert LF, CRLF, CR and NEL into LF
* - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control characters
* - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite
* codepoints
* - @ref UTF8PROC_STABLE - prohibit combining characters that would violate
* the unicode versioning stability
*
* @return
* In case of success, the length (in codepoints) of the normalized UTF-32 string is
* returned; otherwise, a negative error code is returned (@ref utf8proc_errmsg).
*
* @warning The entries of the array pointed to by `str` have to be in the
* range `0x0000` to `0x10FFFF`. Otherwise, the program might crash!
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options);
/**
* Reencodes the sequence of `length` codepoints pointed to by `buffer`
* UTF-8 data in-place (i.e., the result is also stored in `buffer`).
* Can optionally normalize the UTF-32 sequence prior to UTF-8 conversion.
*
* @param buffer the (native-endian UTF-32) unicode codepoints to re-encode.
* @param length the length (in codepoints) of the buffer.
* @param options a bitwise or (`|`) of one or more of the following flags:
* - @ref UTF8PROC_NLF2LS - convert LF, CRLF, CR and NEL into LS
* - @ref UTF8PROC_NLF2PS - convert LF, CRLF, CR and NEL into PS
* - @ref UTF8PROC_NLF2LF - convert LF, CRLF, CR and NEL into LF
* - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control characters
* - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite
* codepoints
* - @ref UTF8PROC_STABLE - prohibit combining characters that would violate
* the unicode versioning stability
* - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster
*
* @return
* In case of success, the length (in bytes) of the resulting nul-terminated
* UTF-8 string is returned; otherwise, a negative error code is returned
* (@ref utf8proc_errmsg).
*
* @warning The amount of free space pointed to by `buffer` must
* exceed the amount of the input data by one byte, and the
* entries of the array pointed to by `str` have to be in the
* range `0x0000` to `0x10FFFF`. Otherwise, the program might crash!
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t *buffer, utf8proc_ssize_t length, utf8proc_option_t options);
/**
* Given a pair of consecutive codepoints, return whether a grapheme break is
* permitted between them (as defined by the extended grapheme clusters in UAX#29).
*
* @param codepoint1 The first codepoint.
* @param codepoint2 The second codepoint, occurring consecutively after `codepoint1`.
* @param state Beginning with Version 29 (Unicode 9.0.0), this algorithm requires
* state to break graphemes. This state can be passed in as a pointer
* in the `state` argument and should initially be set to 0. If the
* state is not passed in (i.e. a null pointer is passed), UAX#29 rules
* GB10/12/13 which require this state will not be applied, essentially
* matching the rules in Unicode 8.0.0.
*
* @warning If the state parameter is used, `utf8proc_grapheme_break_stateful` must
* be called IN ORDER on ALL potential breaks in a string. However, it
* is safe to reset the state to zero after a grapheme break.
*/
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful(
utf8proc_int32_t codepoint1, utf8proc_int32_t codepoint2, utf8proc_int32_t *state);
/**
* Same as @ref utf8proc_grapheme_break_stateful, except without support for the
* Unicode 9 additions to the algorithm. Supported for legacy reasons.
*/
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break(
utf8proc_int32_t codepoint1, utf8proc_int32_t codepoint2);
/**
* Given a codepoint `c`, return the codepoint of the corresponding
* lower-case character, if any; otherwise (if there is no lower-case
* variant, or if `c` is not a valid codepoint) return `c`.
*/
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c);
/**
* Given a codepoint `c`, return the codepoint of the corresponding
* upper-case character, if any; otherwise (if there is no upper-case
* variant, or if `c` is not a valid codepoint) return `c`.
*/
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c);
/**
* Given a codepoint `c`, return the codepoint of the corresponding
* title-case character, if any; otherwise (if there is no title-case
* variant, or if `c` is not a valid codepoint) return `c`.
*/
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c);
/**
* Given a codepoint, return a character width analogous to `wcwidth(codepoint)`,
* except that a width of 0 is returned for non-printable codepoints
* instead of -1 as in `wcwidth`.
*
* @note
* If you want to check for particular types of non-printable characters,
* (analogous to `isprint` or `iscntrl`), use @ref utf8proc_category. */
UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t codepoint);
/**
* Return the Unicode category for the codepoint (one of the
* @ref utf8proc_category_t constants.)
*/
UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t codepoint);
/**
* Return the two-letter (nul-terminated) Unicode category string for
* the codepoint (e.g. `"Lu"` or `"Co"`).
*/
UTF8PROC_DLLEXPORT const char *utf8proc_category_string(utf8proc_int32_t codepoint);
/**
* Maps the given UTF-8 string pointed to by `str` to a new UTF-8
* string, allocated dynamically by `malloc` and returned via `dstptr`.
*
* If the @ref UTF8PROC_NULLTERM flag in the `options` field is set,
* the length is determined by a NULL terminator, otherwise the
* parameter `strlen` is evaluated to determine the string length, but
* in any case the result will be NULL terminated (though it might
* contain NULL characters with the string if `str` contained NULL
* characters). Other flags in the `options` field are passed to the
* functions defined above, and regarded as described. See also
* @ref utf8proc_map_custom to supply a custom codepoint transformation.
*
* In case of success the length of the new string is returned,
* otherwise a negative error code is returned.
*
* @note The memory of the new UTF-8 string will have been allocated
* with `malloc`, and should therefore be deallocated with `free`.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options
);
/**
* Like @ref utf8proc_map, but also takes a `custom_func` mapping function
* that is called on each codepoint in `str` before any other transformations
* (along with a `custom_data` pointer that is passed through to `custom_func`).
* The `custom_func` argument is ignored if it is `NULL`.
*/
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom(
const utf8proc_uint8_t *str, utf8proc_ssize_t strlen, utf8proc_uint8_t **dstptr, utf8proc_option_t options,
utf8proc_custom_func custom_func, void *custom_data
);
/** @name Unicode normalization
*
* Returns a pointer to newly allocated memory of a NFD, NFC, NFKD, NFKC or
* NFKC_Casefold normalized version of the null-terminated string `str`. These
* are shortcuts to calling @ref utf8proc_map with @ref UTF8PROC_NULLTERM
* combined with @ref UTF8PROC_STABLE and flags indicating the normalization.
*/
/** @{ */
/** NFD normalization (@ref UTF8PROC_DECOMPOSE). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFD(const utf8proc_uint8_t *str);
/** NFC normalization (@ref UTF8PROC_COMPOSE). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFC(const utf8proc_uint8_t *str);
/** NFKD normalization (@ref UTF8PROC_DECOMPOSE and @ref UTF8PROC_COMPAT). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKD(const utf8proc_uint8_t *str);
/** NFKC normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT). */
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC(const utf8proc_uint8_t *str);
/**
* NFKC_Casefold normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT
* and @ref UTF8PROC_CASEFOLD and @ref UTF8PROC_IGNORE).
**/
UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8_t *str);
/** @} */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
# add_definitions()
set(EXTRA_CORE_LIBS ${ZLIB_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZSTD_LIBRARIES})
set(EXTRA_CORE_LIBS ${ZLIB_LIBRARIES} ${ICU_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZSTD_LIBRARIES})
set(CORE_PUBLIC_HEADERS
${CORE_PUBLIC_HEADERS}
@ -239,19 +239,9 @@ include_directories(
${CMAKE_BINARY_DIR}/include/QtCore
${CMAKE_BINARY_DIR}/privateinclude/QtCore
${ZLIB_INCLUDE_DIRS}
${ICU_INCLUDES}
${OPENSSL_INCLUDE_DIR}
${ZSTD_INCLUDES}
${CMAKE_SOURCE_DIR}/src/3rdparty/utf8proc
)
set(CORE_SOURCES
${CORE_SOURCES}
${CMAKE_SOURCE_DIR}/src/3rdparty/utf8proc/utf8proc.c
)
set(CORE_HEADERS
${CORE_HEADERS}
${CMAKE_SOURCE_DIR}/src/3rdparty/utf8proc/utf8proc.h
)
if(${KATIE_PLATFORM} STREQUAL "linux")

View file

@ -42,9 +42,9 @@
#include "qchar.h"
#include "qdatastream.h"
#include "qtextcodec.h"
#include "qunicodetables_p.h"
#include "utf8proc.h"
#include <unicode/uchar.h>
#include <unicode/unorm2.h>
QT_BEGIN_NAMESPACE
@ -407,22 +407,23 @@ static inline uint to_ascii_upper(uint ucs4)
description of the values.
\value NoDecomposition
\value Circle
\value Compat
\value Final
\value Canonical
\value Font
\value Fraction
\value Initial
\value Isolated
\value Medial
\value Narrow
\value NoBreak
\value Small
\value Square
\value Sub
\value Initial
\value Medial
\value Final
\value Isolated
\value Circle
\value Super
\value Sub
\value Vertical
\value Wide
\value Narrow
\value Small
\value Square
\value Compat
\value Fraction
\sa decomposition()
*/
@ -600,15 +601,7 @@ QChar::QChar(const uchar ch)
*/
bool QChar::isPrint() const
{
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
case UTF8PROC_CATEGORY_CC:
case UTF8PROC_CATEGORY_CN:
return false;
default:
return true;
}
return true;
return u_isprint(ucs);
}
/*!
@ -619,17 +612,7 @@ bool QChar::isSpace() const
{
if(ucs >= 9 && ucs <= 13)
return true;
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
case UTF8PROC_CATEGORY_ZS:
case UTF8PROC_CATEGORY_ZL:
case UTF8PROC_CATEGORY_ZP:
return true;
default:
return false;
}
return false;
return u_isblank(ucs);
}
/*!
@ -640,11 +623,11 @@ bool QChar::isSpace() const
*/
bool QChar::isMark() const
{
const utf8proc_category_t category = utf8proc_category(ucs);
const int8_t category = u_charType(ucs);
switch (category) {
case UTF8PROC_CATEGORY_MN:
case UTF8PROC_CATEGORY_MC:
case UTF8PROC_CATEGORY_ME:
case U_NON_SPACING_MARK:
case U_COMBINING_SPACING_MARK:
case U_ENCLOSING_MARK:
return true;
default:
return false;
@ -658,20 +641,7 @@ bool QChar::isMark() const
*/
bool QChar::isPunct() const
{
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
case UTF8PROC_CATEGORY_PC:
case UTF8PROC_CATEGORY_PD:
case UTF8PROC_CATEGORY_PS:
case UTF8PROC_CATEGORY_PE:
case UTF8PROC_CATEGORY_PI:
case UTF8PROC_CATEGORY_PF:
case UTF8PROC_CATEGORY_PO:
return true;
default:
return false;
}
return false;
return u_ispunct(ucs);
}
/*!
@ -680,18 +650,7 @@ bool QChar::isPunct() const
*/
bool QChar::isLetter() const
{
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
case UTF8PROC_CATEGORY_LU:
case UTF8PROC_CATEGORY_LL:
case UTF8PROC_CATEGORY_LT:
case UTF8PROC_CATEGORY_LM:
case UTF8PROC_CATEGORY_LO:
return true;
default:
return false;
}
return false;
return u_isalpha(ucs);
}
/*!
@ -705,16 +664,7 @@ bool QChar::isNumber() const
if (is_ascii_char(ucs)) {
return is_ascii_number(ucs);
}
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
case UTF8PROC_CATEGORY_ND:
case UTF8PROC_CATEGORY_NL:
case UTF8PROC_CATEGORY_NO:
return true;
default:
return false;
}
return false;
return u_isxdigit(ucs);
}
/*!
@ -726,23 +676,7 @@ bool QChar::isLetterOrNumber() const
if (is_ascii_char(ucs)) {
return is_ascii_letterornumber(ucs);
}
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
// letter
case UTF8PROC_CATEGORY_LU:
case UTF8PROC_CATEGORY_LL:
case UTF8PROC_CATEGORY_LT:
case UTF8PROC_CATEGORY_LM:
case UTF8PROC_CATEGORY_LO:
// number
case UTF8PROC_CATEGORY_ND:
case UTF8PROC_CATEGORY_NL:
case UTF8PROC_CATEGORY_NO:
return true;
default:
return false;
}
return false;
return u_isalnum(ucs);
}
@ -755,14 +689,7 @@ bool QChar::isDigit() const
if (is_ascii_char(ucs)) {
return is_ascii_number(ucs);
}
const utf8proc_category_t category = utf8proc_category(ucs);
switch (category) {
case UTF8PROC_CATEGORY_ND:
return true;
default:
return false;
}
return false;
return u_isdigit(ucs);
}
@ -772,12 +699,12 @@ bool QChar::isDigit() const
*/
bool QChar::isSymbol() const
{
const utf8proc_category_t category = utf8proc_category(ucs);
const int8_t category = u_charType(ucs);
switch (category) {
case UTF8PROC_CATEGORY_SM:
case UTF8PROC_CATEGORY_SC:
case UTF8PROC_CATEGORY_SK:
case UTF8PROC_CATEGORY_SO:
case U_MATH_SYMBOL:
case U_CURRENCY_SYMBOL:
case U_MODIFIER_SYMBOL:
case U_OTHER_SYMBOL:
return true;
default:
return false;
@ -859,7 +786,7 @@ bool QChar::isSymbol() const
*/
int QChar::digitValue() const
{
return QUnicodeTables::digitValue(ucs);
return QChar::digitValue(ucs);
}
/*!
@ -869,7 +796,7 @@ int QChar::digitValue() const
*/
int QChar::digitValue(const ushort ucs2)
{
return QUnicodeTables::digitValue(ucs2);
return QChar::digitValue(uint(ucs2));
}
/*!
@ -879,71 +806,71 @@ int QChar::digitValue(const ushort ucs2)
*/
int QChar::digitValue(const uint ucs4)
{
return QUnicodeTables::digitValue(ucs4);
return u_digit(ucs4, 10);
}
#define QCHAR_CATEGORY(c) \
const utf8proc_category_t category = utf8proc_category(c); \
const int8_t category = u_charType(c); \
switch (category) { \
case UTF8PROC_CATEGORY_CN: \
case U_GENERAL_OTHER_TYPES: \
return QChar::Other_NotAssigned; \
case UTF8PROC_CATEGORY_LU: \
case U_UPPERCASE_LETTER: \
return QChar::Letter_Uppercase; \
case UTF8PROC_CATEGORY_LL: \
case U_LOWERCASE_LETTER: \
return QChar::Letter_Lowercase; \
case UTF8PROC_CATEGORY_LT: \
case U_TITLECASE_LETTER: \
return QChar::Letter_Titlecase; \
case UTF8PROC_CATEGORY_LM: \
case U_MODIFIER_LETTER: \
return QChar::Letter_Modifier; \
case UTF8PROC_CATEGORY_LO: \
case U_OTHER_LETTER: \
return QChar::Letter_Other; \
case UTF8PROC_CATEGORY_MN: \
case U_NON_SPACING_MARK: \
return QChar::Mark_NonSpacing; \
case UTF8PROC_CATEGORY_MC: \
case U_COMBINING_SPACING_MARK: \
return QChar::Mark_SpacingCombining; \
case UTF8PROC_CATEGORY_ME: \
case U_ENCLOSING_MARK: \
return QChar::Mark_Enclosing; \
case UTF8PROC_CATEGORY_ND: \
case U_DECIMAL_DIGIT_NUMBER: \
return QChar::Number_DecimalDigit; \
case UTF8PROC_CATEGORY_NL: \
case U_LETTER_NUMBER: \
return QChar::Number_Letter; \
case UTF8PROC_CATEGORY_NO: \
case U_OTHER_NUMBER: \
return QChar::Number_Other; \
case UTF8PROC_CATEGORY_PC: \
case U_CONNECTOR_PUNCTUATION: \
return QChar::Punctuation_Connector; \
case UTF8PROC_CATEGORY_PD: \
case U_DASH_PUNCTUATION: \
return QChar::Punctuation_Dash; \
case UTF8PROC_CATEGORY_PS: \
case U_START_PUNCTUATION: \
return QChar::Punctuation_Open; \
case UTF8PROC_CATEGORY_PE: \
case U_END_PUNCTUATION: \
return QChar::Punctuation_Close; \
case UTF8PROC_CATEGORY_PI: \
case U_INITIAL_PUNCTUATION: \
return QChar::Punctuation_InitialQuote; \
case UTF8PROC_CATEGORY_PF: \
case U_FINAL_PUNCTUATION: \
return QChar::Punctuation_FinalQuote; \
case UTF8PROC_CATEGORY_PO: \
case U_OTHER_PUNCTUATION: \
return QChar::Punctuation_Other; \
case UTF8PROC_CATEGORY_SM: \
case U_MATH_SYMBOL: \
return QChar::Symbol_Math; \
case UTF8PROC_CATEGORY_SC: \
case U_CURRENCY_SYMBOL: \
return QChar::Symbol_Currency; \
case UTF8PROC_CATEGORY_SK: \
case U_MODIFIER_SYMBOL: \
return QChar::Symbol_Modifier; \
case UTF8PROC_CATEGORY_SO: \
case U_OTHER_SYMBOL: \
return QChar::Symbol_Other; \
case UTF8PROC_CATEGORY_ZS: \
case U_SPACE_SEPARATOR: \
return QChar::Separator_Space; \
case UTF8PROC_CATEGORY_ZL: \
case U_LINE_SEPARATOR: \
return QChar::Separator_Line; \
case UTF8PROC_CATEGORY_ZP: \
case U_PARAGRAPH_SEPARATOR: \
return QChar::Separator_Paragraph; \
case UTF8PROC_CATEGORY_CC: \
case U_CONTROL_CHAR: \
return QChar::Other_Control; \
case UTF8PROC_CATEGORY_CF: \
case U_FORMAT_CHAR: \
return QChar::Other_Format; \
case UTF8PROC_CATEGORY_CS: \
case U_SURROGATE: \
return QChar::Other_Surrogate; \
case UTF8PROC_CATEGORY_CO: \
case U_PRIVATE_USE_CHAR: \
return QChar::Other_PrivateUse; \
} \
return QChar::Other_NotAssigned;
@ -976,53 +903,53 @@ QChar::Category QChar::category(const ushort ucs2)
}
#define QCHAR_DIRECTION(c) \
const utf8proc_property_t *property = utf8proc_get_property(c); \
switch (property->bidi_class) { \
case UTF8PROC_BIDI_CLASS_L: \
const UCharDirection direction = u_charDirection(c); \
switch (direction) { \
case U_LEFT_TO_RIGHT: \
return QChar::DirL; \
case UTF8PROC_BIDI_CLASS_LRE: \
case U_LEFT_TO_RIGHT_EMBEDDING: \
return QChar::DirLRE; \
case UTF8PROC_BIDI_CLASS_LRO: \
case U_LEFT_TO_RIGHT_OVERRIDE: \
return QChar::DirLRO; \
case UTF8PROC_BIDI_CLASS_R: \
case U_RIGHT_TO_LEFT: \
return QChar::DirR; \
case UTF8PROC_BIDI_CLASS_AL: \
case U_RIGHT_TO_LEFT_ARABIC: \
return QChar::DirAL; \
case UTF8PROC_BIDI_CLASS_RLE: \
case U_RIGHT_TO_LEFT_EMBEDDING: \
return QChar::DirRLE; \
case UTF8PROC_BIDI_CLASS_RLO: \
case U_RIGHT_TO_LEFT_OVERRIDE: \
return QChar::DirRLO; \
case UTF8PROC_BIDI_CLASS_PDF: \
case U_POP_DIRECTIONAL_FORMAT: \
return QChar::DirPDF; \
case UTF8PROC_BIDI_CLASS_EN: \
case U_EUROPEAN_NUMBER: \
return QChar::DirEN; \
case UTF8PROC_BIDI_CLASS_ES: \
case U_EUROPEAN_NUMBER_SEPARATOR: \
return QChar::DirES; \
case UTF8PROC_BIDI_CLASS_ET: \
case U_EUROPEAN_NUMBER_TERMINATOR: \
return QChar::DirET; \
case UTF8PROC_BIDI_CLASS_AN: \
case U_ARABIC_NUMBER: \
return QChar::DirAN; \
case UTF8PROC_BIDI_CLASS_CS: \
case U_COMMON_NUMBER_SEPARATOR: \
return QChar::DirCS; \
case UTF8PROC_BIDI_CLASS_NSM: \
case U_DIR_NON_SPACING_MARK: \
return QChar::DirNSM; \
case UTF8PROC_BIDI_CLASS_BN: \
case U_BOUNDARY_NEUTRAL: \
return QChar::DirBN; \
case UTF8PROC_BIDI_CLASS_B: \
case U_BLOCK_SEPARATOR: \
return QChar::DirB; \
case UTF8PROC_BIDI_CLASS_S: \
case U_SEGMENT_SEPARATOR: \
return QChar::DirS; \
case UTF8PROC_BIDI_CLASS_WS: \
case U_WHITE_SPACE_NEUTRAL: \
return QChar::DirWS; \
case UTF8PROC_BIDI_CLASS_ON: \
case U_OTHER_NEUTRAL: \
return QChar::DirON; \
case UTF8PROC_BIDI_CLASS_LRI: \
case U_LEFT_TO_RIGHT_ISOLATE: \
return QChar::DirLRI; \
case UTF8PROC_BIDI_CLASS_RLI: \
case U_RIGHT_TO_LEFT_ISOLATE: \
return QChar::DirRLI; \
case UTF8PROC_BIDI_CLASS_FSI: \
case U_FIRST_STRONG_ISOLATE: \
return QChar::DirFSI; \
case UTF8PROC_BIDI_CLASS_PDI: \
case U_POP_DIRECTIONAL_ISOLATE: \
return QChar::DirPDI; \
} \
return QChar::DirL;
@ -1059,18 +986,7 @@ QChar::Direction QChar::direction(const ushort ucs2)
*/
QChar::Joining QChar::joining() const
{
return QUnicodeTables::joining(ucs);
}
/*!
\overload
Returns information about the joining properties of the UCS-4-encoded
character specified by \a ucs4 (needed for certain languages such as
Arabic).
*/
QChar::Joining QChar::joining(const uint ucs4)
{
return QUnicodeTables::joining(ucs4);
return QChar::joining(uint(ucs));
}
/*!
@ -1081,9 +997,35 @@ QChar::Joining QChar::joining(const uint ucs4)
*/
QChar::Joining QChar::joining(const ushort ucs2)
{
return QUnicodeTables::joining(ucs2);
return QChar::joining(uint(ucs2));
}
/*!
\overload
Returns information about the joining properties of the UCS-4-encoded
character specified by \a ucs4 (needed for certain languages such as
Arabic).
*/
QChar::Joining QChar::joining(const uint ucs4)
{
const int32_t property = u_getIntPropertyValue(ucs4, UCHAR_JOINING_TYPE);
switch (property) {
case U_JT_JOIN_CAUSING:
return QChar::Causing;
case U_JT_DUAL_JOINING:
return QChar::Dual;
case U_JT_LEFT_JOINING:
return QChar::Left;
case U_JT_RIGHT_JOINING:
return QChar::Right;
case U_JT_TRANSPARENT:
return QChar::Transparent;
case U_JT_NON_JOINING:
// for compatibility
return QChar::OtherJoining;
}
return QChar::OtherJoining;
}
/*!
Returns true if the character should be reversed if the text
@ -1098,18 +1040,7 @@ bool QChar::hasMirrored() const
if (is_ascii_char(ucs)) {
return false;
}
const utf8proc_property_t *property = utf8proc_get_property(ucs);
switch (property->bidi_class) {
case UTF8PROC_BIDI_CLASS_R:
case UTF8PROC_BIDI_CLASS_AL:
case UTF8PROC_BIDI_CLASS_RLE:
case UTF8PROC_BIDI_CLASS_RLO:
case UTF8PROC_BIDI_CLASS_RLI:
return true;
default:
return false;
}
return false;
return u_isMirrored(ucs);
}
/*!
@ -1167,19 +1098,7 @@ bool QChar::isTitleCase() const
*/
QChar QChar::mirroredChar() const
{
return QUnicodeTables::mirroredChar(ucs);
}
/*!
\overload
Returns the mirrored character if the UCS-4-encoded character specified
by \a ucs4 is a mirrored character; otherwise returns the character itself.
\sa hasMirrored()
*/
uint QChar::mirroredChar(const uint ucs4)
{
return QUnicodeTables::mirroredChar(ucs4);
return QChar::mirroredChar(ucs);
}
/*!
@ -1191,7 +1110,19 @@ uint QChar::mirroredChar(const uint ucs4)
*/
ushort QChar::mirroredChar(const ushort ucs2)
{
return QUnicodeTables::mirroredChar(ucs2);
return QChar::mirroredChar(uint(ucs2));
}
/*!
\overload
Returns the mirrored character if the UCS-4-encoded character specified
by \a ucs4 is a mirrored character; otherwise returns the character itself.
\sa hasMirrored()
*/
uint QChar::mirroredChar(const uint ucs4)
{
return u_charMirror(ucs4);
}
/*!
@ -1210,14 +1141,26 @@ QString QChar::decomposition() const
*/
QString QChar::decomposition(const uint ucs4)
{
int buffer[4]; // ### use utf8proc_charwidth?
int boundclass;
const ssize_t decresult = utf8proc_decompose_char(ucs4, buffer, sizeof(buffer), UTF8PROC_DECOMPOSE, &boundclass);
if (Q_UNLIKELY(decresult < 1)) {
qWarning("QChar::decomposition: %s", utf8proc_errmsg(decresult));
UErrorCode errorcode = U_ZERO_ERROR;
const UNormalizer2 *normalizer = unorm2_getNFDInstance(&errorcode);
if (Q_UNLIKELY(U_FAILURE(errorcode))) {
qWarning("QChar::decomposition: %s", u_errorName(errorcode));
return QString();
}
return QString::fromUtf8(reinterpret_cast<char*>(buffer), decresult);
UChar buffer[4];
const int32_t decresult = unorm2_getDecomposition(normalizer, ucs4, buffer, sizeof(buffer), &errorcode);
if (Q_UNLIKELY(decresult < 1)) {
// no decomposition value
return QString();
}
if (Q_UNLIKELY(U_FAILURE(errorcode))) {
qWarning("QChar::decomposition: %s", u_errorName(errorcode));
return QString();
}
return QString::fromUtf16(reinterpret_cast<ushort*>(buffer), decresult);
}
/*!
@ -1236,40 +1179,44 @@ QChar::Decomposition QChar::decompositionTag() const
*/
QChar::Decomposition QChar::decompositionTag(const uint ucs4)
{
const utf8proc_property_t *property = utf8proc_get_property(ucs4);
switch (property->decomp_type) {
case UTF8PROC_DECOMP_TYPE_FONT:
const int32_t property = u_getIntPropertyValue(ucs4, UCHAR_DECOMPOSITION_TYPE);
switch (property) {
case U_DT_CANONICAL:
return QChar::Canonical;
case U_DT_FONT:
return QChar::Font;
case UTF8PROC_DECOMP_TYPE_NOBREAK:
case U_DT_NOBREAK:
return QChar::NoBreak;
case UTF8PROC_DECOMP_TYPE_INITIAL:
case U_DT_INITIAL:
return QChar::Initial;
case UTF8PROC_DECOMP_TYPE_MEDIAL:
case U_DT_MEDIAL:
return QChar::Medial;
case UTF8PROC_DECOMP_TYPE_FINAL:
case U_DT_FINAL:
return QChar::Final;
case UTF8PROC_DECOMP_TYPE_ISOLATED:
case U_DT_ISOLATED:
return QChar::Isolated;
case UTF8PROC_DECOMP_TYPE_CIRCLE:
case U_DT_CIRCLE:
return QChar::Circle;
case UTF8PROC_DECOMP_TYPE_SUPER:
case U_DT_SUPER:
return QChar::Super;
case UTF8PROC_DECOMP_TYPE_SUB:
case U_DT_SUB:
return QChar::Sub;
case UTF8PROC_DECOMP_TYPE_VERTICAL:
case U_DT_VERTICAL:
return QChar::Vertical;
case UTF8PROC_DECOMP_TYPE_WIDE:
case U_DT_WIDE:
return QChar::Wide;
case UTF8PROC_DECOMP_TYPE_NARROW:
case U_DT_NARROW:
return QChar::Narrow;
case UTF8PROC_DECOMP_TYPE_SMALL:
case U_DT_SMALL:
return QChar::Small;
case UTF8PROC_DECOMP_TYPE_SQUARE:
case U_DT_SQUARE:
return QChar::Square;
case UTF8PROC_DECOMP_TYPE_FRACTION:
case U_DT_FRACTION:
return QChar::Fraction;
case UTF8PROC_DECOMP_TYPE_COMPAT:
case U_DT_COMPAT:
return QChar::Compat;
U_DT_NONE:
return QChar::NoDecomposition;
}
return QChar::NoDecomposition;
}
@ -1279,17 +1226,7 @@ QChar::Decomposition QChar::decompositionTag(const uint ucs4)
*/
QChar::UnicodeVersion QChar::unicodeVersion() const
{
return QUnicodeTables::unicodeVersion(ucs);
}
/*!
\overload
Returns the Unicode version that introduced the character specified in
its UCS-4-encoded form as \a ucs4.
*/
QChar::UnicodeVersion QChar::unicodeVersion(const uint ucs4)
{
return QUnicodeTables::unicodeVersion(ucs4);
return QChar::unicodeVersion(ucs);
}
/*!
@ -1299,7 +1236,67 @@ QChar::UnicodeVersion QChar::unicodeVersion(const uint ucs4)
*/
QChar::UnicodeVersion QChar::unicodeVersion(const ushort ucs2)
{
return QUnicodeTables::unicodeVersion(ucs2);
return QChar::unicodeVersion(uint(ucs2));
}
/*!
\overload
Returns the Unicode version that introduced the character specified in
its UCS-4-encoded form as \a ucs4.
*/
QChar::UnicodeVersion QChar::unicodeVersion(const uint ucs4)
{
UVersionInfo info;
u_charAge(ucs4, info);
QByteArray version(U_MAX_VERSION_STRING_LENGTH, Qt::Uninitialized);
u_versionToString(info, version.data());
if (version == "1.1") {
return QChar::Unicode_1_1;
} else if (version == "2.0") {
return QChar::Unicode_2_0;
} else if (version == "2.1") {
return QChar::Unicode_2_1;
} else if (version == "3.0") {
return QChar::Unicode_3_0;
} else if (version == "3.1") {
return QChar::Unicode_3_1;
} else if (version == "3.2") {
return QChar::Unicode_3_2;
} else if (version == "4.0") {
return QChar::Unicode_4_0;
} else if (version == "4.1") {
return QChar::Unicode_4_1;
} else if (version == "5.0") {
return QChar::Unicode_5_0;
} else if (version == "5.1") {
return QChar::Unicode_5_1;
} else if (version == "5.2") {
return QChar::Unicode_5_2;
} else if (version == "6.0") {
return QChar::Unicode_6_0;
} else if (version == "6.1") {
return QChar::Unicode_6_1;
} else if (version == "6.2") {
return QChar::Unicode_6_2;
} else if (version == "6.3") {
return QChar::Unicode_6_3;
} else if (version == "7.0") {
return QChar::Unicode_7_0;
} else if (version == "8.0") {
return QChar::Unicode_8_0;
} else if (version == "9.0") {
return QChar::Unicode_9_0;
} else if (version == "10.0") {
return QChar::Unicode_10_0;
} else if (version == "11.0") {
return QChar::Unicode_11_0;
} else if (version == "12.0") {
return QChar::Unicode_12_0;
} else if (version == "12.1") {
return QChar::Unicode_12_1;
}
return QChar::Unicode_Unassigned;
}
/*!
@ -1318,10 +1315,18 @@ QChar::UnicodeVersion QChar::currentUnicodeVersion()
*/
QChar QChar::toLower() const
{
if (is_ascii_char(ucs)) {
return to_ascii_lower(ucs);
}
return utf8proc_tolower(ucs);
return QChar::toLower(ucs);
}
/*!
\overload
Returns the lowercase equivalent of the UCS-2-encoded character specified
by \a ucs2 if the character is uppercase or titlecase; otherwise returns
the character itself.
*/
ushort QChar::toLower(const ushort ucs2)
{
return QChar::toLower(uint(ucs2));
}
/*!
@ -1335,21 +1340,7 @@ uint QChar::toLower(const uint ucs4)
if (is_ascii_char(ucs4)) {
return to_ascii_lower(ucs4);
}
return utf8proc_tolower(ucs4);
}
/*!
\overload
Returns the lowercase equivalent of the UCS-2-encoded character specified
by \a ucs2 if the character is uppercase or titlecase; otherwise returns
the character itself.
*/
ushort QChar::toLower(const ushort ucs2)
{
if (is_ascii_char(ucs2)) {
return to_ascii_lower(ucs2);
}
return utf8proc_tolower(ucs2);
return u_tolower(ucs4);
}
/*!
@ -1358,10 +1349,18 @@ ushort QChar::toLower(const ushort ucs2)
*/
QChar QChar::toUpper() const
{
if (is_ascii_char(ucs)) {
return to_ascii_upper(ucs);
}
return utf8proc_toupper(ucs);
return QChar::toUpper(ucs);
}
/*!
\overload
Returns the uppercase equivalent of the UCS-2-encoded character specified
by \a ucs2 if the character is lowercase or titlecase; otherwise returns
the character itself.
*/
ushort QChar::toUpper(const ushort ucs2)
{
return QChar::toUpper(uint(ucs2));
}
/*!
@ -1375,21 +1374,7 @@ uint QChar::toUpper(const uint ucs4)
if (is_ascii_char(ucs4)) {
return to_ascii_upper(ucs4);
}
return utf8proc_toupper(ucs4);
}
/*!
\overload
Returns the uppercase equivalent of the UCS-2-encoded character specified
by \a ucs2 if the character is lowercase or titlecase; otherwise returns
the character itself.
*/
ushort QChar::toUpper(const ushort ucs2)
{
if (is_ascii_char(ucs2)) {
return to_ascii_upper(ucs2);
}
return utf8proc_toupper(ucs2);
return u_toupper(ucs4);
}
/*!
@ -1398,10 +1383,18 @@ ushort QChar::toUpper(const ushort ucs2)
*/
QChar QChar::toTitleCase() const
{
if (is_ascii_char(ucs)) {
return to_ascii_upper(ucs);
}
return utf8proc_totitle(ucs);
return QChar::toTitleCase(ucs);
}
/*!
\overload
Returns the title case equivalent of the UCS-2-encoded character specified
by \a ucs2 if the character is lowercase or uppercase; otherwise returns
the character itself.
*/
ushort QChar::toTitleCase(const ushort ucs2)
{
return QChar::toTitleCase(uint(ucs2));
}
/*!
@ -1415,21 +1408,7 @@ uint QChar::toTitleCase(const uint ucs4)
if (is_ascii_char(ucs4)) {
return to_ascii_upper(ucs4);
}
return utf8proc_totitle(ucs4);
}
/*!
\overload
Returns the title case equivalent of the UCS-2-encoded character specified
by \a ucs2 if the character is lowercase or uppercase; otherwise returns
the character itself.
*/
ushort QChar::toTitleCase(const ushort ucs2)
{
if (is_ascii_char(ucs2)) {
return to_ascii_upper(ucs2);
}
return utf8proc_totitle(ucs2);
return u_totitle(ucs4);
}
/*!
@ -1438,17 +1417,17 @@ ushort QChar::toTitleCase(const ushort ucs2)
*/
QChar QChar::toCaseFolded() const
{
if (is_ascii_char(ucs)) {
return to_ascii_lower(ucs);
}
int buffer[4]; // ### use utf8proc_charwidth?
int boundclass;
const ssize_t decresult = utf8proc_decompose_char(ucs, buffer, sizeof(buffer), UTF8PROC_CASEFOLD, &boundclass);
if (Q_UNLIKELY(decresult < 1)) {
qWarning("QChar::toCaseFolded: %s", utf8proc_errmsg(decresult));
return QChar(ucs);
}
return QChar(*buffer);
return QChar::toCaseFolded(ucs);
}
/*!
\overload
Returns the case folded equivalent of the UCS-2-encoded character specified
by \a ucs2. For most Unicode characters this is the same as toLowerCase().
*/
ushort QChar::toCaseFolded(const ushort ucs2)
{
return QChar::toCaseFolded(uint(ucs2));
}
/*!
@ -1461,37 +1440,9 @@ uint QChar::toCaseFolded(const uint ucs4)
if (is_ascii_char(ucs4)) {
return to_ascii_lower(ucs4);
}
int buffer[4]; // ### use utf8proc_charwidth?
int boundclass;
const ssize_t decresult = utf8proc_decompose_char(ucs4, buffer, sizeof(buffer), UTF8PROC_CASEFOLD, &boundclass);
if (Q_UNLIKELY(decresult < 1)) {
qWarning("QChar::toCaseFolded: %s", utf8proc_errmsg(decresult));
return ucs4;
}
return uint(*buffer);
return u_foldCase(ucs4, U_FOLD_CASE_DEFAULT);
}
/*!
\overload
Returns the case folded equivalent of the UCS-2-encoded character specified
by \a ucs2. For most Unicode characters this is the same as toLowerCase().
*/
ushort QChar::toCaseFolded(const ushort ucs2)
{
if (is_ascii_char(ucs2)) {
return to_ascii_lower(ucs2);
}
int buffer[4]; // ### use utf8proc_charwidth?
int boundclass;
const ssize_t decresult = utf8proc_decompose_char(ucs2, buffer, sizeof(buffer), UTF8PROC_CASEFOLD, &boundclass);
if (Q_UNLIKELY(decresult < 1)) {
qWarning("QChar::toCaseFolded: %s", utf8proc_errmsg(decresult));
return ucs2;
}
return ushort(*buffer);
}
/*!
\fn char QChar::latin1() const

View file

@ -149,6 +149,7 @@ public:
enum Decomposition {
NoDecomposition,
Canonical,
Font,
NoBreak,
Initial,

View file

@ -50,7 +50,6 @@
#include "qendian.h"
#include "qmutex.h"
#include "qcorecommon_p.h"
#include "utf8proc.h"
#include <limits.h>
#include <string.h>
@ -58,6 +57,8 @@
#include <stdio.h>
#include <stdarg.h>
#include <unicode/unorm2.h>
QT_BEGIN_NAMESPACE
#ifndef QT_NO_TEXTCODEC
@ -5756,31 +5757,51 @@ QString QString::repeated(int times) const
void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from)
{
Q_UNUSED(version);
const utf8proc_uint8_t *d = reinterpret_cast<const utf8proc_uint8_t*>(data->constData() + from);
utf8proc_uint8_t *p = Q_NULLPTR;
UErrorCode errorcode = U_ZERO_ERROR;
const UNormalizer2 *normalizer = Q_NULLPTR;
switch (mode) {
case QString::NormalizationForm_D: {
p = utf8proc_NFKD(d);
normalizer = unorm2_getNFDInstance(&errorcode);
break;
}
case QString::NormalizationForm_C: {
p = utf8proc_NFC(d);
normalizer = unorm2_getNFCInstance(&errorcode);
break;
}
case QString::NormalizationForm_KD: {
p = utf8proc_NFKD(d);
normalizer = unorm2_getNFKDInstance(&errorcode);
break;
}
case QString::NormalizationForm_KC: {
p = utf8proc_NFKC(d);
normalizer = unorm2_getNFKCInstance(&errorcode);
break;
}
}
data->setUtf16(reinterpret_cast<const ushort*>(p), qstrlen(reinterpret_cast<char*>(p)));
if (p)
::free(p);
if (Q_UNLIKELY(U_FAILURE(errorcode))) {
qWarning("QString::normalized: %s", u_errorName(errorcode));
data->clear();
return;
}
const int size = data->size() - from;
UChar buffer[size * 2];
const int32_t decresult = unorm2_normalize(normalizer, reinterpret_cast<const UChar*>(data->unicode() + from),
size, buffer, sizeof(buffer), &errorcode);
if (Q_UNLIKELY(decresult < 1)) {
// no normalization value
data->clear();
return;
}
if (Q_UNLIKELY(U_FAILURE(errorcode))) {
qWarning("QString::normalized: %s", u_errorName(errorcode));
data->clear();
return;
}
data->setUnicode(reinterpret_cast<const QChar*>(buffer), decresult);
}
/*!

File diff suppressed because it is too large Load diff

View file

@ -53,21 +53,6 @@ QT_BEGIN_NAMESPACE
namespace QUnicodeTables {
// required by QChar
Q_CORE_EXPORT int QT_FASTCALL digitValue(uint ucs4);
inline int QT_FASTCALL digitValue(ushort ucs2)
{ return QUnicodeTables::digitValue(uint(ucs2)); }
Q_CORE_EXPORT QChar::Joining QT_FASTCALL joining(uint ucs4);
inline QChar::Joining QT_FASTCALL joining(ushort ucs2)
{ return QUnicodeTables::joining(uint(ucs2)); }
Q_CORE_EXPORT uint QT_FASTCALL mirroredChar(uint ucs4);
inline ushort QT_FASTCALL mirroredChar(ushort ucs2)
{ return QUnicodeTables::mirroredChar(uint(ucs2)); }
Q_CORE_EXPORT QChar::UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4);
inline QChar::UnicodeVersion QT_FASTCALL unicodeVersion(ushort ucs2)
{ return QUnicodeTables::unicodeVersion(uint(ucs2)); }
// required by Harfbuzz
enum CombiningClass {
Combining_NotOrdered = 0,

View file

@ -7,7 +7,7 @@ include_directories(
${CMAKE_BINARY_DIR}/include/QtCore
${CMAKE_BINARY_DIR}/privateinclude/QtCore
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/3rdparty/utf8proc
${ICU_INCLUDES}
)
set(MOC_SOURCES
@ -87,11 +87,11 @@ set(BOOTSTRAP_SOURCES
${CMAKE_SOURCE_DIR}/src/core/tools/qlocale_unix.cpp
${CMAKE_SOURCE_DIR}/src/core/tools/qlocale_std.cpp
${CMAKE_SOURCE_DIR}/src/core/tools/qunicodetables.cpp
${CMAKE_SOURCE_DIR}/src/3rdparty/utf8proc/utf8proc.c
)
add_executable(bootstrap_moc ${BOOTSTRAP_SOURCES} ${MOC_SOURCES})
target_compile_definitions(bootstrap_moc PRIVATE ${BOOTSTRAP_DEFINITIONS})
target_link_libraries(bootstrap_moc ${ICU_LIBRARIES})
add_executable(moc ${MOC_SOURCES})
target_link_libraries(moc ${EXTRA_MOC_LIBS})

View file

@ -44,10 +44,6 @@
#include <QTextCodec>
#include <QtTest/QtTest>
#if !defined(QWS) && defined(Q_OS_MAC)
#include "qcore_mac_p.h"
#endif
#ifdef Q_OS_UNIX
#include <sys/ipc.h>
#include <sys/mman.h>
@ -83,18 +79,6 @@ private slots:
void toLower() const;
void toUpper() const;
void toCaseFolded() const;
#if !defined(QWS) && defined(Q_OS_MAC)
void QCFString_data() const;
void QCFString_toCFStringRef_data() const;
void QCFString_toCFStringRef() const;
void QCFString_operatorCFStringRef_data() const;
void QCFString_operatorCFStringRef() const;
void QCFString_toQString_data() const;
void QCFString_toQString() const;
void QCFString_operatorQString_data() const;
void QCFString_operatorQString() const;
#endif // !defined(QWS) && defined(Q_OS_MAC)
};
void tst_QString::equals() const