diff options
| author | Mattias Andrée <m@maandree.se> | 2026-01-24 21:31:58 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-01-24 21:31:58 +0100 |
| commit | 6b568aa1bca7f7f502af7b57303ec2673b331c8f (patch) | |
| tree | 584870f81a8f5ecb093af3ff05aab8114de96b7d | |
| parent | Add superscript and subscript (so far only with digits) and lycian and lydian (diff) | |
| download | charconv-6b568aa1bca7f7f502af7b57303ec2673b331c8f.tar.gz charconv-6b568aa1bca7f7f502af7b57303ec2673b331c8f.tar.bz2 charconv-6b568aa1bca7f7f502af7b57303ec2673b331c8f.tar.xz | |
Add domino tiles
Signed-off-by: Mattias Andrée <m@maandree.se>
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | convert-to-domino-tiles.c | 22 | ||||
| -rw-r--r-- | libcharconv.h | 72 | ||||
| -rw-r--r-- | libcharconv_domino_tiles_horizontal.c | 85 | ||||
| -rw-r--r-- | libcharconv_domino_tiles_vertical.c | 85 | ||||
| -rw-r--r-- | libcharconv_latin.c | 17 |
6 files changed, 286 insertions, 2 deletions
@@ -48,7 +48,8 @@ BIN =\ convert-to-superscript\ convert-to-subscript\ convert-to-lydian\ - convert-to-lycian + convert-to-lycian\ + convert-to-domino-tiles LIBOBJ =\ libcharconv_decode_utf8_.o\ @@ -84,7 +85,9 @@ LIBOBJ =\ libcharconv_superscript.o\ libcharconv_subscript.o\ libcharconv_lydian.o\ - libcharconv_lycian.o + libcharconv_lycian.o\ + libcharconv_domino_tiles_horizontal.o\ + libcharconv_domino_tiles_vertical.o LOBJ = $(LIBOBJ:.o=.lo) diff --git a/convert-to-domino-tiles.c b/convert-to-domino-tiles.c new file mode 100644 index 0000000..abb33f4 --- /dev/null +++ b/convert-to-domino-tiles.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-h | -v]"); + + +int +main(int argc, char *argv[]) +{ + int vertical = 0; + + ARGBEGIN { + case 'h': vertical = 0; break; + case 'v': vertical = 1; break; + default: + usage(); + } ARGEND; + if (argc) + usage(); + + return convert(vertical ? &libcharconv_domino_tiles_vertical : &libcharconv_domino_tiles_horizontal); +} diff --git a/libcharconv.h b/libcharconv.h index 9eab393..9eac800 100644 --- a/libcharconv.h +++ b/libcharconv.h @@ -1093,4 +1093,76 @@ enum libcharconv_result libcharconv_lydian(const char *s, size_t slen, size_t *n enum libcharconv_result libcharconv_lycian(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp); +/** + * Convert a pair of [0, 6]-digits to domino tiles, + * or "##" to the back of a domino tiles. The tile + * will be horizontal by default, but '|' or '-' can + * be added between the two symbols to select + * horizontal ('|') or vertical ('-') orientation + * + * @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_domino_tiles_horizontal(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp); + + +/** + * Convert a pair of [0, 6]-digits to domino tiles, + * or "##" to the back of a domino tiles. The tile + * will be vertical by default, but '|' or '-' can + * be added between the two symbols to select + * horizontal ('|') or vertical ('-') orientation + * + * @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_domino_tiles_vertical(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp); + + #endif diff --git a/libcharconv_domino_tiles_horizontal.c b/libcharconv_domino_tiles_horizontal.c new file mode 100644 index 0000000..5edf493 --- /dev/null +++ b/libcharconv_domino_tiles_horizontal.c @@ -0,0 +1,85 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" + + +enum libcharconv_result +libcharconv_domino_tiles_horizontal(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t c; + int vertical; + *n = 0; + for (; slen--; s++) { + if ('0' <= s[0] && s[0] <= '6') { + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + vertical = 0; + if (s[1] == '|') + vertical = 0; + else if (s[1] == '-') + vertical = 1; + else if ('0' <= s[1] && s[1] <= '6') + goto conv2; + else + goto no_match; + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + if ('0' <= s[2] && s[2] <= '6') + goto conv3; + goto no_match; + } else if (s[0] == '#') { + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + vertical = 0; + if (s[1] == '|') + vertical = 0; + else if (s[1] == '-') + vertical = 1; + else if (s[1] == '#') + goto conv2; + else + goto no_match; + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + if (s[2] == '#') + goto conv3; + goto no_match; + } else { + no_match: + *n += 1u; + } + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +conv2: + if (*n) + goto no_conv; + if (*ncp) { + if (s[0] == '#') + c = UINT32_C(0x1F030); + else + c = UINT32_C(0x1F031) + (unsigned)(s[0] - '0') * 7u + (unsigned)(s[1] - '0'); + if (vertical) + c += UINT32_C(0x1F062) - UINT32_C(0x1F030); + *cp = c; + } + *n += 2u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv3: + if (*n) + goto no_conv; + if (*ncp) { + if (s[0] == '#') + c = UINT32_C(0x1F030); + else + c = UINT32_C(0x1F031) + (unsigned)(s[0] - '0') * 7u + (unsigned)(s[2] - '0'); + if (vertical) + c += UINT32_C(0x1F062) - UINT32_C(0x1F030); + *cp = c; + } + *n += 3u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} diff --git a/libcharconv_domino_tiles_vertical.c b/libcharconv_domino_tiles_vertical.c new file mode 100644 index 0000000..0df1841 --- /dev/null +++ b/libcharconv_domino_tiles_vertical.c @@ -0,0 +1,85 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" + + +enum libcharconv_result +libcharconv_domino_tiles_vertical(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t c; + int vertical; + *n = 0; + for (; slen--; s++) { + if ('0' <= s[0] && s[0] <= '6') { + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + vertical = 1; + if (s[1] == '|') + vertical = 0; + else if (s[1] == '-') + vertical = 1; + else if ('0' <= s[1] && s[1] <= '6') + goto conv2; + else + goto no_match; + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + if ('0' <= s[2] && s[2] <= '6') + goto conv3; + goto no_match; + } else if (s[0] == '#') { + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + vertical = 1; + if (s[1] == '|') + vertical = 0; + else if (s[1] == '-') + vertical = 1; + else if (s[1] == '#') + goto conv2; + else + goto no_match; + if (!slen--) + return LIBCHARCONV_INDETERMINATE; + if (s[2] == '#') + goto conv3; + goto no_match; + } else { + no_match: + *n += 1u; + } + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +conv2: + if (*n) + goto no_conv; + if (*ncp) { + if (s[0] == '#') + c = UINT32_C(0x1F030); + else + c = UINT32_C(0x1F031) + (unsigned)(s[0] - '0') * 7u + (unsigned)(s[1] - '0'); + if (vertical) + c += UINT32_C(0x1F062) - UINT32_C(0x1F030); + *cp = c; + } + *n += 2u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv3: + if (*n) + goto no_conv; + if (*ncp) { + if (s[0] == '#') + c = UINT32_C(0x1F030); + else + c = UINT32_C(0x1F031) + (unsigned)(s[0] - '0') * 7u + (unsigned)(s[2] - '0'); + if (vertical) + c += UINT32_C(0x1F062) - UINT32_C(0x1F030); + *cp = c; + } + *n += 3u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} diff --git a/libcharconv_latin.c b/libcharconv_latin.c index 60a2fb5..77ab4c9 100644 --- a/libcharconv_latin.c +++ b/libcharconv_latin.c @@ -327,6 +327,19 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz c = (uint_least32_t)"aebBgdiwzDjkqlmnMNupKrstTAEhx"[c - UINT32_C(0x10280)]; goto conv; + } else if (UINT32_C(0x1F031) <= c && c <= UINT32_C(0x1F061)) { + /* domino tiles */ + c1 = (char)(((uint_least32_t)c - UINT32_C(0x1F031)) / 7u + (unsigned)'0'); + c3 = (char)(((uint_least32_t)c - UINT32_C(0x1F031)) % 7u + (unsigned)'0'); + c2 = '|'; + goto conv3; + } else if (UINT32_C(0x1F063) <= c && c <= UINT32_C(0x1F093)) { + /* domino tiles */ + c1 = (char)(((uint_least32_t)c - UINT32_C(0x1F063)) / 7u + (unsigned)'0'); + c3 = (char)(((uint_least32_t)c - UINT32_C(0x1F063)) % 7u + (unsigned)'0'); + c2 = '-'; + goto conv3; + } else { switch (c) { /* shogi */ @@ -459,6 +472,10 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz /* lydian */ case UINT32_C(0x1093F): c = (uint_least32_t)'"'; goto conv; + /* domino tiles */ + case UINT32_C(0x1F030): c1 = '#'; c2 = '|'; c3 = '#'; goto conv3; + case UINT32_C(0x1F062): c1 = '#'; c2 = '-'; c3 = '#'; goto conv3; + default: no_match: *n += clen; |
