aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-25 12:04:20 +0100
committerMattias Andrée <m@maandree.se>2026-01-25 12:04:20 +0100
commita7c404e03a4b814160ec4c97797a56ee4581a0f7 (patch)
treeac3c598e792f041826438e8fe81e31ce5ca92d6b
parentAdd lisu (diff)
downloadcharconv-a7c404e03a4b814160ec4c97797a56ee4581a0f7.tar.gz
charconv-a7c404e03a4b814160ec4c97797a56ee4581a0f7.tar.bz2
charconv-a7c404e03a4b814160ec4c97797a56ee4581a0f7.tar.xz
Add yijing n-grams
Signed-off-by: Mattias Andrée <m@maandree.se>
-rw-r--r--Makefile14
-rw-r--r--convert-to-yijing-digrams.c18
-rw-r--r--convert-to-yijing-hexagrams.c18
-rw-r--r--convert-to-yijing-monograms.c18
-rw-r--r--convert-to-yijing-tetragrams.c18
-rw-r--r--convert-to-yijing-trigrams.c18
-rw-r--r--libcharconv.h200
-rw-r--r--libcharconv_latin.c82
-rw-r--r--libcharconv_yijing_digrams.c51
-rw-r--r--libcharconv_yijing_hexagrams.c69
-rw-r--r--libcharconv_yijing_monograms.c31
-rw-r--r--libcharconv_yijing_tetragrams.c46
-rw-r--r--libcharconv_yijing_trigrams.c41
13 files changed, 601 insertions, 23 deletions
diff --git a/Makefile b/Makefile
index e3e3c01..8e03a4f 100644
--- a/Makefile
+++ b/Makefile
@@ -54,7 +54,12 @@ BIN =\
convert-to-ocr\
convert-to-crop-marks\
convert-to-braille\
- convert-to-lisu
+ convert-to-lisu\
+ convert-to-yijing-monograms\
+ convert-to-yijing-digrams\
+ convert-to-yijing-trigrams\
+ convert-to-yijing-tetragrams\
+ convert-to-yijing-hexagrams
LIBOBJ =\
libcharconv_decode_utf8_.o\
@@ -97,7 +102,12 @@ LIBOBJ =\
libcharconv_ocr.o\
libcharconv_crop_marks.o\
libcharconv_braille.o\
- libcharconv_lisu.o
+ libcharconv_lisu.o\
+ libcharconv_yijing_monograms.o\
+ libcharconv_yijing_digrams.o\
+ libcharconv_yijing_trigrams.o\
+ libcharconv_yijing_tetragrams.o\
+ libcharconv_yijing_hexagrams.o
LOBJ = $(LIBOBJ:.o=.lo)
diff --git a/convert-to-yijing-digrams.c b/convert-to-yijing-digrams.c
new file mode 100644
index 0000000..5240adf
--- /dev/null
+++ b/convert-to-yijing-digrams.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("");
+
+
+int
+main(int argc, char *argv[])
+{
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ return convert(&libcharconv_yijing_digrams);
+}
diff --git a/convert-to-yijing-hexagrams.c b/convert-to-yijing-hexagrams.c
new file mode 100644
index 0000000..16b0da7
--- /dev/null
+++ b/convert-to-yijing-hexagrams.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("");
+
+
+int
+main(int argc, char *argv[])
+{
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ return convert(&libcharconv_yijing_hexagrams);
+}
diff --git a/convert-to-yijing-monograms.c b/convert-to-yijing-monograms.c
new file mode 100644
index 0000000..e4a8ce1
--- /dev/null
+++ b/convert-to-yijing-monograms.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("");
+
+
+int
+main(int argc, char *argv[])
+{
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ return convert(&libcharconv_yijing_monograms);
+}
diff --git a/convert-to-yijing-tetragrams.c b/convert-to-yijing-tetragrams.c
new file mode 100644
index 0000000..2c0c2dd
--- /dev/null
+++ b/convert-to-yijing-tetragrams.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("");
+
+
+int
+main(int argc, char *argv[])
+{
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ return convert(&libcharconv_yijing_tetragrams);
+}
diff --git a/convert-to-yijing-trigrams.c b/convert-to-yijing-trigrams.c
new file mode 100644
index 0000000..c135119
--- /dev/null
+++ b/convert-to-yijing-trigrams.c
@@ -0,0 +1,18 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("");
+
+
+int
+main(int argc, char *argv[])
+{
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ return convert(&libcharconv_yijing_trigrams);
+}
diff --git a/libcharconv.h b/libcharconv.h
index 9c77b1f..1be4782 100644
--- a/libcharconv.h
+++ b/libcharconv.h
@@ -326,7 +326,7 @@ enum libcharconv_result libcharconv_latin(const char *s, size_t slen, size_t *n,
/**
- * Preforms convertion from Latin to Cypriot
+ * Convert from Latin to Cypriot
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -358,7 +358,7 @@ enum libcharconv_result libcharconv_cypriot(const char *s, size_t slen, size_t *
/**
- * Preforms convertion from Latin to MATHEMATICAL BOLD
+ * Convert from Latin to MATHEMATICAL BOLD
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -390,7 +390,7 @@ enum libcharconv_result libcharconv_bold(const char *s, size_t slen, size_t *n,
/**
- * Preforms convertion from Latin to MATHEMATICAL ITALIC
+ * Convert from Latin to MATHEMATICAL ITALIC
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -422,7 +422,7 @@ enum libcharconv_result libcharconv_italic(const char *s, size_t slen, size_t *n
/**
- * Preforms convertion from Latin to MATHEMATICAL BOLD ITALIC
+ * Convert from Latin to MATHEMATICAL BOLD ITALIC
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -454,7 +454,7 @@ enum libcharconv_result libcharconv_bold_italic(const char *s, size_t slen, size
/**
- * Preforms convertion from Latin to MATHEMATICAL MONOSPACE
+ * Convert from Latin to MATHEMATICAL MONOSPACE
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -486,7 +486,7 @@ enum libcharconv_result libcharconv_monospace(const char *s, size_t slen, size_t
/**
- * Preforms convertion from DIGITs to SEGMENTED DIGITs
+ * Convert from DIGITs to SEGMENTED DIGITs
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -518,7 +518,7 @@ enum libcharconv_result libcharconv_segmented(const char *s, size_t slen, size_t
/**
- * Preforms convertion from Latin to MATHEMATICAL SANS-SERIF
+ * Convert from Latin to MATHEMATICAL SANS-SERIF
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -550,7 +550,7 @@ enum libcharconv_result libcharconv_sans_serif(const char *s, size_t slen, size_
/**
- * Preforms convertion from Latin to MATHEMATICAL SANS-SERIF BOLD
+ * Convert from Latin to MATHEMATICAL SANS-SERIF BOLD
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -582,7 +582,7 @@ enum libcharconv_result libcharconv_sans_serif_bold(const char *s, size_t slen,
/**
- * Preforms convertion from Latin to MATHEMATICAL SANS-SERIF ITALIC
+ * Convert from Latin to MATHEMATICAL SANS-SERIF ITALIC
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -614,7 +614,7 @@ enum libcharconv_result libcharconv_sans_serif_italic(const char *s, size_t slen
/**
- * Preforms convertion from Latin to MATHEMATICAL SANS-SERIF BOLD ITALIC
+ * Convert from Latin to MATHEMATICAL SANS-SERIF BOLD ITALIC
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -646,7 +646,7 @@ enum libcharconv_result libcharconv_sans_serif_bold_italic(const char *s, size_t
/**
- * Preforms convertion from Latin to MATHEMATICAL DOUBLE-STRUCK
+ * Convert from Latin to MATHEMATICAL DOUBLE-STRUCK
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -678,7 +678,7 @@ enum libcharconv_result libcharconv_double_struck(const char *s, size_t slen, si
/**
- * Preforms convertion from Latin to DOUBLE-STRUCK ITALIC
+ * Convert from Latin to DOUBLE-STRUCK ITALIC
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -710,7 +710,7 @@ enum libcharconv_result libcharconv_double_struck_italic(const char *s, size_t s
/**
- * Preforms convertion from Latin to MATHEMATICAL FRAKTUR
+ * Convert from Latin to MATHEMATICAL FRAKTUR
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -742,7 +742,7 @@ enum libcharconv_result libcharconv_fraktur(const char *s, size_t slen, size_t *
/**
- * Preforms convertion from Latin to MATHEMATICAL BOLD FRAKTUR
+ * Convert from Latin to MATHEMATICAL BOLD FRAKTUR
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -774,7 +774,7 @@ enum libcharconv_result libcharconv_bold_fraktur(const char *s, size_t slen, siz
/**
- * Preforms convertion from Latin to MATHEMATICAL SCRIPT
+ * Convert from Latin to MATHEMATICAL SCRIPT
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -806,7 +806,7 @@ enum libcharconv_result libcharconv_script(const char *s, size_t slen, size_t *n
/**
- * Preforms convertion from Latin to MATHEMATICAL BOLD SCRIPT
+ * Convert from Latin to MATHEMATICAL BOLD SCRIPT
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -838,7 +838,7 @@ enum libcharconv_result libcharconv_bold_script(const char *s, size_t slen, size
/**
- * Preforms convertion from Latin to Buhid
+ * Convert from Latin to Buhid
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -1032,7 +1032,7 @@ enum libcharconv_result libcharconv_subscript(const char *s, size_t slen, size_t
/**
- * Preforms convertion from Latin to Lydian
+ * Convert from Latin to Lydian
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -1064,7 +1064,7 @@ enum libcharconv_result libcharconv_lydian(const char *s, size_t slen, size_t *n
/**
- * Preforms convertion from Latin to Lycian
+ * Convert from Latin to Lycian
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -1314,7 +1314,7 @@ enum libcharconv_result libcharconv_braille(const char *s, size_t slen, size_t *
/**
- * Preforms convertion from Latin to Lisu
+ * Convert from Latin to Lisu
*
* @param s Text to convert
* @param slen The number of bytes available in `s`
@@ -1345,4 +1345,164 @@ enum libcharconv_result libcharconv_braille(const char *s, size_t slen, size_t *
enum libcharconv_result libcharconv_lisu(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp);
+/**
+ * Convert from [1, 3]-digits to Yijing monograms
+ *
+ * @param s Text to convert
+ * @param slen The number of bytes available in `s`
+ * @param n Output parameter for the number of consumed bytes
+ * @param cp Output buffer for the codepoints
+ * @param ncp Input parameter for the number of codepoints that
+ * fit in `cp`, and output parameter for the number
+ * of output codepoints (if it exceeds the original
+ * value of `ncp`, a larger buffer is needed)
+ * @return LIBCHARCONV_NO_CONVERT:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that cannot be converted
+ * LIBCHARCONV_CONVERTED:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that was converted to a codepoint which
+ * is stored in `*cp`
+ * LIBCHARCONV_INDETERMINATE:
+ * If all text has been input, no more can be
+ * converted, otherwise more of the text most
+ * be made available before the function can
+ * determine whether the beginning of `s` can be
+ * converted or what it should be converted to
+ * LIBCHARCONV_CONVERT_IF_END:
+ * As LIBCHARCONV_CONVERTED the entire text has
+ * been input, as LIBCHARCONV_INDETERMINATE
+ * otherwise
+ */
+enum libcharconv_result libcharconv_yijing_monograms(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp);
+
+
+/**
+ * Convert from [1, 3]-digit sequences to Yijing digrams
+ *
+ * @param s Text to convert
+ * @param slen The number of bytes available in `s`
+ * @param n Output parameter for the number of consumed bytes
+ * @param cp Output buffer for the codepoints
+ * @param ncp Input parameter for the number of codepoints that
+ * fit in `cp`, and output parameter for the number
+ * of output codepoints (if it exceeds the original
+ * value of `ncp`, a larger buffer is needed)
+ * @return LIBCHARCONV_NO_CONVERT:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that cannot be converted
+ * LIBCHARCONV_CONVERTED:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that was converted to a codepoint which
+ * is stored in `*cp`
+ * LIBCHARCONV_INDETERMINATE:
+ * If all text has been input, no more can be
+ * converted, otherwise more of the text most
+ * be made available before the function can
+ * determine whether the beginning of `s` can be
+ * converted or what it should be converted to
+ * LIBCHARCONV_CONVERT_IF_END:
+ * As LIBCHARCONV_CONVERTED the entire text has
+ * been input, as LIBCHARCONV_INDETERMINATE
+ * otherwise
+ */
+enum libcharconv_result libcharconv_yijing_digrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp);
+
+
+/**
+ * Convert from [1, 2]-digit sequences to Yijing trigrams
+ *
+ * @param s Text to convert
+ * @param slen The number of bytes available in `s`
+ * @param n Output parameter for the number of consumed bytes
+ * @param cp Output buffer for the codepoints
+ * @param ncp Input parameter for the number of codepoints that
+ * fit in `cp`, and output parameter for the number
+ * of output codepoints (if it exceeds the original
+ * value of `ncp`, a larger buffer is needed)
+ * @return LIBCHARCONV_NO_CONVERT:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that cannot be converted
+ * LIBCHARCONV_CONVERTED:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that was converted to a codepoint which
+ * is stored in `*cp`
+ * LIBCHARCONV_INDETERMINATE:
+ * If all text has been input, no more can be
+ * converted, otherwise more of the text most
+ * be made available before the function can
+ * determine whether the beginning of `s` can be
+ * converted or what it should be converted to
+ * LIBCHARCONV_CONVERT_IF_END:
+ * As LIBCHARCONV_CONVERTED the entire text has
+ * been input, as LIBCHARCONV_INDETERMINATE
+ * otherwise
+ */
+enum libcharconv_result libcharconv_yijing_trigrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp);
+
+
+/**
+ * Convert from [1, 3]-digit sequences to Yijing tetragrams
+ *
+ * @param s Text to convert
+ * @param slen The number of bytes available in `s`
+ * @param n Output parameter for the number of consumed bytes
+ * @param cp Output buffer for the codepoints
+ * @param ncp Input parameter for the number of codepoints that
+ * fit in `cp`, and output parameter for the number
+ * of output codepoints (if it exceeds the original
+ * value of `ncp`, a larger buffer is needed)
+ * @return LIBCHARCONV_NO_CONVERT:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that cannot be converted
+ * LIBCHARCONV_CONVERTED:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that was converted to a codepoint which
+ * is stored in `*cp`
+ * LIBCHARCONV_INDETERMINATE:
+ * If all text has been input, no more can be
+ * converted, otherwise more of the text most
+ * be made available before the function can
+ * determine whether the beginning of `s` can be
+ * converted or what it should be converted to
+ * LIBCHARCONV_CONVERT_IF_END:
+ * As LIBCHARCONV_CONVERTED the entire text has
+ * been input, as LIBCHARCONV_INDETERMINATE
+ * otherwise
+ */
+enum libcharconv_result libcharconv_yijing_tetragrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp);
+
+
+/**
+ * Convert from [1, 2]-digit sequences to Yijing hexagrams
+ *
+ * @param s Text to convert
+ * @param slen The number of bytes available in `s`
+ * @param n Output parameter for the number of consumed bytes
+ * @param cp Output buffer for the codepoints
+ * @param ncp Input parameter for the number of codepoints that
+ * fit in `cp`, and output parameter for the number
+ * of output codepoints (if it exceeds the original
+ * value of `ncp`, a larger buffer is needed)
+ * @return LIBCHARCONV_NO_CONVERT:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that cannot be converted
+ * LIBCHARCONV_CONVERTED:
+ * `*n` is the number of bytes from the beginning
+ * of `s` that was converted to a codepoint which
+ * is stored in `*cp`
+ * LIBCHARCONV_INDETERMINATE:
+ * If all text has been input, no more can be
+ * converted, otherwise more of the text most
+ * be made available before the function can
+ * determine whether the beginning of `s` can be
+ * converted or what it should be converted to
+ * LIBCHARCONV_CONVERT_IF_END:
+ * As LIBCHARCONV_CONVERTED the entire text has
+ * been input, as LIBCHARCONV_INDETERMINATE
+ * otherwise
+ */
+enum libcharconv_result libcharconv_yijing_hexagrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp);
+
+
#endif
diff --git a/libcharconv_latin.c b/libcharconv_latin.c
index 9dc81cf..232eb5c 100644
--- a/libcharconv_latin.c
+++ b/libcharconv_latin.c
@@ -2,12 +2,24 @@
#include "lib-common.h"
+static unsigned char yijing_hexagrams[] = {
+ 0xC0, 0xEB, 0xCC, 0xE0, 0xC9, 0xC5, 0xD8, 0xCB,
+ 0xC8, 0xF8, 0xE4, 0xF4, 0xFC, 0xFA, 0xE9, 0xD3,
+ 0xCD, 0xF1, 0xDD, 0xF7, 0xE5, 0xFF, 0xD4, 0xE2,
+ 0xD9, 0xD1, 0xD5, 0xF3, 0xE8, 0xC3, 0xDA, 0xD6,
+ 0xEA, 0xDB, 0xF0, 0xDE, 0xF9, 0xEE, 0xD0, 0xEC,
+ 0xC4, 0xEF, 0xFE, 0xE6, 0xFB, 0xDC, 0xC2, 0xC7,
+ 0xE1, 0xDF, 0xF6, 0xFD, 0xF5, 0xE7, 0xF2, 0xCF,
+ 0xCA, 0xED, 0xE3, 0xCE, 0xD2, 0xC6, 0xD7, 0xC1
+};
+
+
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;
- char c1, c2, c3, c4, c5;
+ char c1, c2, c3, c4, c5, c6;
size_t i, clen;
unsigned num;
@@ -389,6 +401,39 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
goto use_switch;
goto conv1;
+ } else if (UINT32_C(0x2630) <= c && c <= UINT32_C(0x2637)) {
+ /* yijing trigrams */
+ c1 = (c & 1u) ? '2' : '1';
+ c2 = (c & 2u) ? '2' : '1';
+ c3 = (c & 4u) ? '2' : '1';
+ goto conv3;
+
+ } else if (UINT32_C(0x1D306) <= c && c <= UINT32_C(0x1D356)) {
+ /* yijing tetragrams */
+ c -= UINT32_C(0x1D306);
+ c4 = (char)((c % 3u) + (unsigned)'1');
+ c /= 3u;
+ c3 = (char)((c % 3u) + (unsigned)'1');
+ c /= 3u;
+ c2 = (char)((c % 3u) + (unsigned)'1');
+ c /= 3u;
+ c1 = (char)((c % 3u) + (unsigned)'1');
+ goto conv4;
+
+ } else if (UINT32_C(0x4DC0) <= c && c <= UINT32_C(0x4DFF)) {
+ /* yijing hexagrams */
+ c &= 0xFFu;
+ for (i = 0u;; i++)
+ if (yijing_hexagrams[i] == (unsigned char)c)
+ break;
+ c6 = (i & 1u) ? '2' : '1';
+ c5 = (i & 2u) ? '2' : '1';
+ c4 = (i & 4u) ? '2' : '1';
+ c3 = (i & 8u) ? '2' : '1';
+ c2 = (i & 16u) ? '2' : '1';
+ c1 = (i & 32u) ? '2' : '1';
+ goto conv6;
+
} else {
use_switch:
switch (c) {
@@ -542,6 +587,22 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
case UINT32_C(0xA4FA): c1 = '.'; c2 = '.'; goto conv2;
case UINT32_C(0x11FB0): c1 = 'Y'; goto conv1;
+ /* yijing monograms */
+ case UINT32_C(0x268A): c1 = '1'; goto conv1;
+ case UINT32_C(0x268B): c1 = '2'; goto conv1;
+ case UINT32_C(0x1D300): c1 = '3'; goto conv1;
+
+ /* yijing digrams */
+ case UINT32_C(0x268C): c1 = '1'; c2 = '1'; goto conv2;
+ case UINT32_C(0x268E): c1 = '1'; c2 = '2'; goto conv2;
+ case UINT32_C(0x1D301): c1 = '1'; c2 = '3'; goto conv2;
+ case UINT32_C(0x268D): c1 = '2'; c2 = '1'; goto conv2;
+ case UINT32_C(0x268F): c1 = '2'; c2 = '2'; goto conv2;
+ case UINT32_C(0x1D302): c1 = '2'; c2 = '3'; goto conv2;
+ case UINT32_C(0x1D303): c1 = '3'; c2 = '1'; goto conv2;
+ case UINT32_C(0x1D304): c1 = '3'; c2 = '2'; goto conv2;
+ case UINT32_C(0x1D305): c1 = '3'; c2 = '3'; goto conv2;
+
default:
no_match:
*n += clen;
@@ -621,4 +682,23 @@ conv5:
cp[4] = (uint_least32_t)c5;
*ncp = 5u;
return ret;
+
+conv6:
+ if (*n)
+ goto no_conv;
+ *n += clen;
+ if (*ncp >= 1u)
+ cp[0] = (uint_least32_t)c1;
+ if (*ncp >= 2u)
+ cp[1] = (uint_least32_t)c2;
+ if (*ncp >= 3u)
+ cp[2] = (uint_least32_t)c3;
+ if (*ncp >= 4u)
+ cp[3] = (uint_least32_t)c4;
+ if (*ncp >= 5u)
+ cp[4] = (uint_least32_t)c5;
+ if (*ncp >= 6u)
+ cp[5] = (uint_least32_t)c6;
+ *ncp = 6u;
+ return ret;
}
diff --git a/libcharconv_yijing_digrams.c b/libcharconv_yijing_digrams.c
new file mode 100644
index 0000000..91bc36f
--- /dev/null
+++ b/libcharconv_yijing_digrams.c
@@ -0,0 +1,51 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_yijing_digrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ *n = 0;
+ for (; slen--; s++) {
+ if ('1' <= s[0] && s[0] <= '3') {
+ if (!slen)
+ return LIBCHARCONV_INDETERMINATE;
+ if (s[0] == '1' && s[1] == '1')
+ c = UINT32_C(0x268C);
+ else if (s[0] == '1' && s[1] == '2')
+ c = UINT32_C(0x268E);
+ else if (s[0] == '1' && s[1] == '3')
+ c = UINT32_C(0x1D301);
+ else if (s[0] == '2' && s[1] == '1')
+ c = UINT32_C(0x268D);
+ else if (s[0] == '2' && s[1] == '2')
+ c = UINT32_C(0x268F);
+ else if (s[0] == '2' && s[1] == '3')
+ c = UINT32_C(0x1D302);
+ else if (s[0] == '3' && s[1] == '1')
+ c = UINT32_C(0x1D303);
+ else if (s[0] == '3' && s[1] == '2')
+ c = UINT32_C(0x1D304);
+ else if (s[0] == '3' && s[1] == '3')
+ c = UINT32_C(0x1D305);
+ else
+ goto no_match;
+ goto conv;
+ } else {
+ no_match:
+ *n += 1u;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 2u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}
diff --git a/libcharconv_yijing_hexagrams.c b/libcharconv_yijing_hexagrams.c
new file mode 100644
index 0000000..b271e1f
--- /dev/null
+++ b/libcharconv_yijing_hexagrams.c
@@ -0,0 +1,69 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+static unsigned char yijing_hexagrams[] = {
+ 0xC0, 0xEB, 0xCC, 0xE0, 0xC9, 0xC5, 0xD8, 0xCB,
+ 0xC8, 0xF8, 0xE4, 0xF4, 0xFC, 0xFA, 0xE9, 0xD3,
+ 0xCD, 0xF1, 0xDD, 0xF7, 0xE5, 0xFF, 0xD4, 0xE2,
+ 0xD9, 0xD1, 0xD5, 0xF3, 0xE8, 0xC3, 0xDA, 0xD6,
+ 0xEA, 0xDB, 0xF0, 0xDE, 0xF9, 0xEE, 0xD0, 0xEC,
+ 0xC4, 0xEF, 0xFE, 0xE6, 0xFB, 0xDC, 0xC2, 0xC7,
+ 0xE1, 0xDF, 0xF6, 0xFD, 0xF5, 0xE7, 0xF2, 0xCF,
+ 0xCA, 0xED, 0xE3, 0xCE, 0xD2, 0xC6, 0xD7, 0xC1
+};
+
+
+enum libcharconv_result
+libcharconv_yijing_hexagrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ size_t i;
+ *n = 0;
+ for (; slen--; s++) {
+ if ('1' <= s[0] && s[0] <= '2') {
+ if (slen == 0u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[1] || s[1] > '2')
+ goto no_match;
+ if (slen == 1u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[2] || s[2] > '2')
+ goto no_match;
+ if (slen == 2u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[3] || s[3] > '2')
+ goto no_match;
+ if (slen == 3u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[4] || s[4] > '2')
+ goto no_match;
+ if (slen == 4u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[5] || s[5] > '2')
+ goto no_match;
+ i = s[5] == '2' ? 1u : 0u;
+ i |= s[4] == '2' ? 2u : 0u;
+ i |= s[3] == '2' ? 4u : 0u;
+ i |= s[2] == '2' ? 8u : 0u;
+ i |= s[1] == '2' ? 16u : 0u;
+ i |= s[0] == '2' ? 32u : 0u;
+ c = UINT32_C(0x4D00) | yijing_hexagrams[i];
+ goto conv;
+ } else {
+ no_match:
+ *n += 1u;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 6u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}
diff --git a/libcharconv_yijing_monograms.c b/libcharconv_yijing_monograms.c
new file mode 100644
index 0000000..12177ec
--- /dev/null
+++ b/libcharconv_yijing_monograms.c
@@ -0,0 +1,31 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_yijing_monograms(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ *n = 0;
+ for (; slen--; s++) {
+ switch (*s) {
+ case '1': c = UINT32_C(0x268A); goto conv;
+ case '2': c = UINT32_C(0x268B); goto conv;
+ case '3': c = UINT32_C(0x1D300); goto conv;
+ default:
+ *n += 1u;
+ break;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 1u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}
diff --git a/libcharconv_yijing_tetragrams.c b/libcharconv_yijing_tetragrams.c
new file mode 100644
index 0000000..8286417
--- /dev/null
+++ b/libcharconv_yijing_tetragrams.c
@@ -0,0 +1,46 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_yijing_tetragrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ *n = 0;
+ for (; slen--; s++) {
+ if ('1' <= s[0] && s[0] <= '3') {
+ if (slen == 0u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[1] || s[1] > '3')
+ goto no_match;
+ if (slen == 1u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[2] || s[2] > '3')
+ goto no_match;
+ if (slen == 2u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[3] || s[3] > '3')
+ goto no_match;
+ c = UINT32_C(0x1D306);
+ c += (uint_least32_t)(s[3] - '1') * 1u;
+ c += (uint_least32_t)(s[2] - '1') * 3u;
+ c += (uint_least32_t)(s[1] - '1') * 9u;
+ c += (uint_least32_t)(s[0] - '1') * 27u;
+ goto conv;
+ } else {
+ no_match:
+ *n += 1u;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 4u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}
diff --git a/libcharconv_yijing_trigrams.c b/libcharconv_yijing_trigrams.c
new file mode 100644
index 0000000..7292283
--- /dev/null
+++ b/libcharconv_yijing_trigrams.c
@@ -0,0 +1,41 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_yijing_trigrams(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ *n = 0;
+ for (; slen--; s++) {
+ if ('1' <= s[0] && s[0] <= '2') {
+ if (slen == 0u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[1] || s[1] > '2')
+ goto no_match;
+ if (slen == 1u)
+ return LIBCHARCONV_INDETERMINATE;
+ if ('1' > s[2] || s[2] > '2')
+ goto no_match;
+ c = UINT32_C(0x2630);
+ c += (uint_least32_t)(s[0] == '2' ? 1u : 0u);
+ c += (uint_least32_t)(s[1] == '2' ? 2u : 0u);
+ c += (uint_least32_t)(s[2] == '2' ? 4u : 0u);
+ goto conv;
+ } else {
+ no_match:
+ *n += 1u;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 3u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}