aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-25 16:05:05 +0100
committerMattias Andrée <m@maandree.se>2026-01-25 16:05:05 +0100
commita0cd51f0e62cef118c17cfc308ff2a67bef49338 (patch)
tree3e9f0debf88f4398417e79abc7fc31a45ef5922f
parentAdd mirrored (diff)
downloadcharconv-a0cd51f0e62cef118c17cfc308ff2a67bef49338.tar.gz
charconv-a0cd51f0e62cef118c17cfc308ff2a67bef49338.tar.bz2
charconv-a0cd51f0e62cef118c17cfc308ff2a67bef49338.tar.xz
Add turned
Signed-off-by: Mattias Andrée <m@maandree.se>
-rw-r--r--Makefile6
-rw-r--r--convert-to-turned.c4
-rw-r--r--libcharconv.h5
-rw-r--r--libcharconv_flipped.c23
-rw-r--r--libcharconv_latin.c24
-rw-r--r--libcharconv_mirrored.c23
-rw-r--r--libcharconv_turned.c78
7 files changed, 131 insertions, 32 deletions
diff --git a/Makefile b/Makefile
index 5f364f0..1884b4c 100644
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,8 @@ BIN =\
convert-to-flipped\
convert-to-overlaid\
convert-to-joined\
- convert-to-mirrored
+ convert-to-mirrored\
+ convert-to-turned
LIBOBJ =\
libcharconv_decode_utf8_.o\
@@ -117,7 +118,8 @@ LIBOBJ =\
libcharconv_flipped.o\
libcharconv_overlaid.o\
libcharconv_joined.o\
- libcharconv_mirrored.o
+ libcharconv_mirrored.o\
+ libcharconv_turned.o
LOBJ = $(LIBOBJ:.o=.lo)
diff --git a/convert-to-turned.c b/convert-to-turned.c
new file mode 100644
index 0000000..0576ae2
--- /dev/null
+++ b/convert-to-turned.c
@@ -0,0 +1,4 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+SIMPLE(libcharconv_turned)
diff --git a/libcharconv.h b/libcharconv.h
index f5eba1e..adea6e5 100644
--- a/libcharconv.h
+++ b/libcharconv.h
@@ -348,6 +348,11 @@ LIBCHARCONV_FUNC_(libcharconv_joined);
*/
LIBCHARCONV_FUNC_(libcharconv_mirrored);
+/**
+ * Rotate characters 180 degrees
+ */
+LIBCHARCONV_FUNC_(libcharconv_turned);
+
#undef LIBCHARCONV_FUNC_
#endif
diff --git a/libcharconv_flipped.c b/libcharconv_flipped.c
index 43893fc..952d7e6 100644
--- a/libcharconv_flipped.c
+++ b/libcharconv_flipped.c
@@ -30,14 +30,21 @@ libcharconv_flipped(const char *s, size_t slen, size_t *n, uint_least32_t *cp, s
continue;
}
- for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
- if (c == pairs[i].a) {
- c = pairs[i].b;
- goto conv;
- }
- if (c == pairs[i].b) {
- c = pairs[i].a;
- goto conv;
+ if (UINT32_C(0x1F063) <= c && c <= UINT32_C(0x1F093)) {
+ c -= UINT32_C(0x1F063);
+ c = c % 7u * 7u + c / 7u;
+ c += UINT32_C(0x1F063);
+ goto conv;
+ } else {
+ for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
+ if (c == pairs[i].a) {
+ c = pairs[i].b;
+ goto conv;
+ }
+ if (c == pairs[i].b) {
+ c = pairs[i].a;
+ goto conv;
+ }
}
}
diff --git a/libcharconv_latin.c b/libcharconv_latin.c
index 6baf82b..b1a2de2 100644
--- a/libcharconv_latin.c
+++ b/libcharconv_latin.c
@@ -18,7 +18,7 @@ enum libcharconv_result
libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
{
enum libcharconv_result ret = LIBCHARCONV_CONVERTED;
- uint_least32_t c, cp1, cp2;
+ uint_least32_t c;
char c1, c2, c3, c4, c5, c6;
size_t i, clen;
unsigned num;
@@ -627,8 +627,8 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
case UINT32_C(0x2152): c1 = '1'; c2 = '/'; c3 = '1'; c4 = '0'; goto conv4;
/* overlaid */
- case UINT32_C(0x203D): c1 = '!'; c2 = '?'; goto conv2;
- case UINT32_C(0x2E18): cp1 = UINT32_C(0xBF); cp2 = UINT32_C(0xA1); goto conv2cp;
+ case UINT32_C(0x203D):
+ case UINT32_C(0x2E18): c1 = '!'; c2 = '?'; goto conv2;
/* joined */
case UINT32_C(0x2048): c1 = '?'; c2 = '!'; goto conv2;
@@ -641,6 +641,13 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
case UINT32_C(0x2E2E): c = UINT32_C(0x003F); goto conv;
case UINT32_C(0x2143): c = UINT32_C(0x004C); goto conv;
+ /* turned */
+ case UINT32_C(0x218A): c = UINT32_C(0x0032); goto conv;
+ case UINT32_C(0x218B): c = UINT32_C(0x0033); goto conv;
+ case UINT32_C(0x00A1): c = UINT32_C(0x0021); goto conv;
+ case UINT32_C(0x00BF): c = UINT32_C(0x003F); goto conv;
+ case UINT32_C(0x2E35): c = UINT32_C(0x003B); goto conv;
+
default:
no_match:
*n += clen;
@@ -663,17 +670,6 @@ conv:
*ncp = 1u;
return ret;
-conv2cp:
- if (*n)
- goto no_conv;
- *n += clen;
- if (*ncp >= 1u)
- cp[0] = cp1;
- if (*ncp >= 2u)
- cp[1] = cp2;
- *ncp = 2u;
- return ret;
-
conv2:
if (*n)
goto no_conv;
diff --git a/libcharconv_mirrored.c b/libcharconv_mirrored.c
index a95f636..75ae5cb 100644
--- a/libcharconv_mirrored.c
+++ b/libcharconv_mirrored.c
@@ -35,14 +35,21 @@ libcharconv_mirrored(const char *s, size_t slen, size_t *n, uint_least32_t *cp,
continue;
}
- for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
- if (c == pairs[i].a) {
- c = pairs[i].b;
- goto conv;
- }
- if (c == pairs[i].b) {
- c = pairs[i].a;
- goto conv;
+ if (UINT32_C(0x1F031) <= c && c <= UINT32_C(0x1F061)) {
+ c -= UINT32_C(0x1F031);
+ c = c % 7u * 7u + c / 7u;
+ c += UINT32_C(0x1F031);
+ goto conv;
+ } else {
+ for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
+ if (c == pairs[i].a) {
+ c = pairs[i].b;
+ goto conv;
+ }
+ if (c == pairs[i].b) {
+ c = pairs[i].a;
+ goto conv;
+ }
}
}
diff --git a/libcharconv_turned.c b/libcharconv_turned.c
new file mode 100644
index 0000000..8436305
--- /dev/null
+++ b/libcharconv_turned.c
@@ -0,0 +1,78 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+static struct {
+ uint_least32_t a;
+ uint_least32_t b;
+} pairs[] = {
+ {0x0032, 0x218A},
+ {0x0033, 0x218B},
+ {0x2616, 0x26C9},
+ {0x2617, 0x26CA},
+ {0x0021, 0x00A1},
+ {0x003F, 0x00BF},
+ {0x2E35, 0x003B},
+ {0x203D, 0x2E18}
+};
+
+
+enum libcharconv_result
+libcharconv_turned(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ size_t i, clen;
+ *n = 0;
+ while (slen) {
+ clen = libcharconv_decode_utf8_(s, slen, &c);
+ if (clen > slen) {
+ if (*n)
+ goto no_conv;
+ return LIBCHARCONV_INDETERMINATE;
+ }
+ if (!clen) {
+ *n += 1u;
+ slen -= 1u;
+ s = &s[1];
+ continue;
+ }
+
+ if (UINT32_C(0x1F031) <= c && c <= UINT32_C(0x1F061)) {
+ c -= UINT32_C(0x1F031);
+ c = c % 7u * 7u + c / 7u;
+ c += UINT32_C(0x1F031);
+ goto conv;
+ } else if (UINT32_C(0x1F063) <= c && c <= UINT32_C(0x1F093)) {
+ c -= UINT32_C(0x1F063);
+ c = c % 7u * 7u + c / 7u;
+ c += UINT32_C(0x1F063);
+ goto conv;
+ } else {
+ for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
+ if (c == pairs[i].a) {
+ c = pairs[i].b;
+ goto conv;
+ }
+ if (c == pairs[i].b) {
+ c = pairs[i].a;
+ goto conv;
+ }
+ }
+ }
+
+ *n += clen;
+ s = &s[clen];
+ slen -= clen;
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += clen;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}