aboutsummaryrefslogtreecommitdiffstats
path: root/characters.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-10-18 05:55:18 +0200
committerMattias Andrée <m@maandree.se>2026-10-18 05:55:18 +0200
commite578c50ffbd02f2f7b9116b6b9eb096bb1fcee60 (patch)
treea70534fc3c758dd23c494a086e2af46a7d0e602d /characters.c
parentMisc (diff)
downloadgcmap-e578c50ffbd02f2f7b9116b6b9eb096bb1fcee60.tar.gz
gcmap-e578c50ffbd02f2f7b9116b6b9eb096bb1fcee60.tar.bz2
gcmap-e578c50ffbd02f2f7b9116b6b9eb096bb1fcee60.tar.xz
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--characters.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/characters.c b/characters.c
new file mode 100644
index 0000000..5679918
--- /dev/null
+++ b/characters.c
@@ -0,0 +1,80 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+is_noncharacter(uint32_t cp)
+{
+ return (0xFDD0u <= cp && cp <= 0xFDEFu) || (cp & 0xFFFEu) == 0xFFFEu;
+}
+
+
+int
+is_surrogate(uint32_t cp)
+{
+ return 0xD800u <= cp && cp <= 0xDFFFu;
+}
+
+
+int
+is_valid_codepoint(uint32_t cp)
+{
+ return cp <= LIBCMAP_ULTIMATE_CODEPOINT && !is_noncharacter(cp) && !is_surrogate(cp);
+}
+
+
+struct libcmap_codepoint_data *
+get_codepoint_data(uint32_t cp)
+{
+ static char *databuf = NULL;
+ static size_t databufsize = 0u;
+ static struct libcmap_codepoint_data data;
+
+ int r;
+
+again:
+ r = libcmap_get_codepoint_data(cp, &data, databuf, &databufsize);
+ if (r <= 0) {
+ if (!r || errno != ERANGE || !databufsize)
+ return NULL;
+ databuf = erealloc(databuf, databufsize);
+ goto again;
+ }
+
+ return &data;
+}
+
+
+enum codepoint_class
+classify_from_codepoint_data(const struct libcmap_codepoint_data *data)
+{
+ if (!data)
+ return CP_OUT_OF_RANGE;
+
+ switch ((int)(data->general_category & LIBCMAP_GENERAL_SUPERCATEGORY_MASK)) {
+ case LIBCMAP_GENERAL_SUPERCATEGORY_MARK:
+ return CP_COMBINING_MARK;
+ default:
+ break;
+ }
+
+ switch ((int)data->general_category) {
+ case LIBCMAP_GENERAL_CATEGORY_OTHER_CONTROL:
+ return CP_CONTROL;
+ case LIBCMAP_GENERAL_CATEGORY_OTHER_SURROGATE:
+ return CP_SURROGATE;
+ case LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED:
+ return data->noncharacter ? CP_NONCHARACTER : CP_RESERVED;
+ default:
+ break;
+ }
+
+ return CP_REGULAR;
+}
+
+
+enum codepoint_class
+classify_codepoint(uint32_t cp)
+{
+ return classify_from_codepoint_data(get_codepoint_data(cp));
+}