aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-26 20:22:51 +0100
committerMattias Andrée <m@maandree.se>2026-01-26 20:22:51 +0100
commit954ba559821444fdf0af4608b632011fb9c22b87 (patch)
tree25c00a0693fa7b5f39ab2dc80b82ec9f0714bedd
parentAdd dentistry (diff)
downloadcharconv-954ba559821444fdf0af4608b632011fb9c22b87.tar.gz
charconv-954ba559821444fdf0af4608b632011fb9c22b87.tar.bz2
charconv-954ba559821444fdf0af4608b632011fb9c22b87.tar.xz
Add cards
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--Makefile6
-rw-r--r--convert-to-cards.c4
-rw-r--r--libcharconv.h5
-rw-r--r--libcharconv_cards.c138
-rw-r--r--libcharconv_latin.c59
-rw-r--r--libcharconv_negative.c3
6 files changed, 212 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 663c961..c26efd0 100644
--- a/Makefile
+++ b/Makefile
@@ -83,7 +83,8 @@ BIN =\
convert-to-invisible\
convert-to-enclosed\
convert-to-metrical\
- convert-to-dentistry
+ convert-to-dentistry\
+ convert-to-cards
LIBOBJ =\
libcharconv_decode_utf8_.o\
@@ -159,7 +160,8 @@ LIBOBJ =\
libcharconv_enclosed_positive.o\
libcharconv_enclosed_negative.o\
libcharconv_metrical.o\
- libcharconv_dentistry.o
+ libcharconv_dentistry.o\
+ libcharconv_cards.o
LOBJ = $(LIBOBJ:.o=.lo)
diff --git a/convert-to-cards.c b/convert-to-cards.c
new file mode 100644
index 0000000..97e00c3
--- /dev/null
+++ b/convert-to-cards.c
@@ -0,0 +1,4 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+SIMPLE(libcharconv_cards)
diff --git a/libcharconv.h b/libcharconv.h
index 3763577..8e5e1a6 100644
--- a/libcharconv.h
+++ b/libcharconv.h
@@ -491,6 +491,11 @@ LIBCHARCONV_FUNC_(libcharconv_metrical);
*/
LIBCHARCONV_FUNC_(libcharconv_dentistry);
+/**
+ * Convert to PLAYING CARDs and SUITs
+ */
+LIBCHARCONV_FUNC_(libcharconv_cards);
+
#undef LIBCHARCONV_FUNC_
#endif
diff --git a/libcharconv_cards.c b/libcharconv_cards.c
new file mode 100644
index 0000000..9e6b468
--- /dev/null
+++ b/libcharconv_cards.c
@@ -0,0 +1,138 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_cards(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ uint_least32_t c;
+ unsigned value;
+ unsigned j;
+ int num;
+
+ *n = 0;
+ for (; slen--; s++) {
+ switch (*s) {
+ case '#': c = UINT32_C(0x1F0A0); goto conv;
+ case 'f': case 'F': case '0': c = UINT32_C(0x1F0E0); goto conv;
+ case 'r': case 'R': c = UINT32_C(0x1F0BF); goto conv;
+ case 'b': case 'B': c = UINT32_C(0x1F0CF); goto conv;
+ case 'w': case 'W': c = UINT32_C(0x1F0DF); goto conv;
+ case 'S': c = UINT32_C(0x2660); goto conv;
+ case 'h': c = UINT32_C(0x2661); goto conv;
+ case 'd': c = UINT32_C(0x2662); goto conv;
+ case 's': c = UINT32_C(0x2664); goto conv;
+ case 'H': c = UINT32_C(0x2665); goto conv;
+ case 'D': c = UINT32_C(0x2666); goto conv;
+
+ case 'A': case 'a': value = 1u; goto face;
+ case 'J': case 'j': value = 11u; goto face;
+ case 'C': case 'c': value = 12u; goto face;
+ case 'Q': case 'q': value = 13u; goto face;
+ case 'K': case 'k': value = 14u; face:
+ j = 1u;
+ if (!slen) {
+ if (*s == 'C')
+ c = UINT32_C(0x2663);
+ else if (*s == 'c')
+ c = UINT32_C(0x2667);
+ else
+ return LIBCHARCONV_INDETERMINATE;
+ goto conv_if_end;
+ }
+ if (value == 14u && (s[j] == 'N' || s[j] == 'n')) {
+ value = 12u;
+ j++;
+ if (slen == 1u)
+ return LIBCHARCONV_INDETERMINATE;
+ }
+ num = 0;
+ common:
+ if (s[j] == 'S' || s[j] == 's')
+ c = UINT32_C(0x1F0A0) + value;
+ else if (s[j] == 'H' || s[j] == 'h')
+ c = UINT32_C(0x1F0B0) + value;
+ else if (s[j] == 'D' || s[j] == 'd')
+ c = UINT32_C(0x1F0C0) + value;
+ else if (s[j] == 'C' || s[j] == 'c')
+ c = UINT32_C(0x1F0D0) + value;
+ else if (num)
+ goto trump;
+ else if (s[0] == 'C' || s[0] == 'c')
+ goto clubs;
+ else
+ goto no_match;
+ j++;
+ goto convj;
+
+ clubs:
+ j = 1u;
+ c = *s == 'C' ? UINT32_C(0x2663) : UINT32_C(0x2667);
+ goto conv;
+
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8':
+ case '9':
+ value = (unsigned)(*s - '0');
+ j = 1u;
+ if (!slen) {
+ c = UINT32_C(0x1F0E0) + value;
+ goto conv_if_end;
+ }
+ if ('0' <= s[j] && s[j] <= '9') {
+ value *= 10u;
+ value += (unsigned)(s[j] - '0');
+ j++;
+ if (value > 10u) {
+ if (value > 21u) {
+ value /= 10u;
+ j--;
+ }
+ trump:
+ c = UINT32_C(0x1F0E0) + value;
+ goto convj;
+ }
+ if (slen == 1u) {
+ c = UINT32_C(0x1F0E0) + value;
+ goto conv_if_end;
+ }
+ }
+ num = 1;
+ goto common;
+
+ default:
+ no_match:
+ *n += 1u;
+ break;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+conv_if_end:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += j;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERT_IF_END;
+
+conv:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 1u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+
+convj:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += j;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}
diff --git a/libcharconv_latin.c b/libcharconv_latin.c
index a3bc55f..473896a 100644
--- a/libcharconv_latin.c
+++ b/libcharconv_latin.c
@@ -550,6 +550,7 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
c2 = (char)(c - (UINT32_C(0x278A) - (uint_least32_t)'1'));
c3 = ')';
goto conv3;
+
} else if (UINT32_C(0x23D6) <= c && c <= UINT32_C(0x23D9)) {
/* metrical */
c -= (uint_least32_t)UINT32_C(0x23D6) - (uint_least32_t)'2';
@@ -561,6 +562,49 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
c2 = (c & 2u) ? '2' : '1';
goto conv2;
+ } else if (UINT32_C(0x1F0E1) <= c && c <= UINT32_C(0x1F0E9)) {
+ /* cards */
+ c -= (uint_least32_t)UINT32_C(0x1F0E1) - (uint_least32_t)'1';
+ goto conv;
+ } else if (UINT32_C(0x1F0EA) <= c && c <= UINT32_C(0x1F0F3)) {
+ /* cards */
+ c -= (uint_least32_t)UINT32_C(0x1F0EA) - (uint_least32_t)'0';
+ c1 = '1';
+ c2 = (char)c;
+ goto conv2;
+ } else if (UINT32_C(0x1F0F4) <= c && c <= UINT32_C(0x1F0F5)) {
+ /* cards */
+ c -= (uint_least32_t)UINT32_C(0x1F0F4) - (uint_least32_t)'0';
+ c1 = '2';
+ c2 = (char)c;
+ goto conv2;
+ } else if (UINT32_C(0x1F0A1) <= c && c <= UINT32_C(0x1F0AE)) {
+ /* cards */
+ c1 = "A234567890JCQK"[c - UINT32_C(0x1F0A1)];
+ c2 = 'S';
+ goto conv_card;
+ } else if (UINT32_C(0x1F0B1) <= c && c <= UINT32_C(0x1F0BE)) {
+ /* cards */
+ c1 = "A234567890JCQK"[c - UINT32_C(0x1F0B1)];
+ c2 = 'H';
+ goto conv_card;
+ } else if (UINT32_C(0x1F0C1) <= c && c <= UINT32_C(0x1F0CE)) {
+ /* cards */
+ c1 = "A234567890JCQK"[c - UINT32_C(0x1F0C1)];
+ c2 = 'D';
+ goto conv_card;
+ } else if (UINT32_C(0x1F0D1) <= c && c <= UINT32_C(0x1F0DE)) {
+ /* cards */
+ c1 = "A234567890JCQK"[c - UINT32_C(0x1F0D1)];
+ c2 = 'C';
+ conv_card:
+ if (c1 != '0')
+ goto conv2;
+ c3 = c2;
+ c2 = c1;
+ c1 = '1';
+ goto conv3;
+
} else {
use_switch:
switch (c) {
@@ -1011,6 +1055,21 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz
case UINT32_C(0x23C5): c1 = '_'; c2 = 'A'; goto conv2;
case UINT32_C(0x23C8): c1 = '_'; c2 = '~'; goto conv2;
+ /* cards */
+ case UINT32_C(0x1F0A0): c1 = '#'; goto conv1;
+ case UINT32_C(0x1F0BF): c1 = 'r'; goto conv1;
+ case UINT32_C(0x1F0CF): c1 = 'b'; goto conv1;
+ case UINT32_C(0x1F0DF): c1 = 'w'; goto conv1;
+ case UINT32_C(0x1F0E0): c1 = 'f'; goto conv1;
+ case UINT32_C(0x2660): c1 = 'S'; goto conv1;
+ case UINT32_C(0x2661): c1 = 'h'; goto conv1;
+ case UINT32_C(0x2662): c1 = 'd'; goto conv1;
+ case UINT32_C(0x2663): c1 = 'C'; goto conv1;
+ case UINT32_C(0x2664): c1 = 's'; goto conv1;
+ case UINT32_C(0x2665): c1 = 'H'; goto conv1;
+ case UINT32_C(0x2666): c1 = 'D'; goto conv1;
+ case UINT32_C(0x2667): c1 = 'c'; goto conv1;
+
default:
no_match:
*n += clen;
diff --git a/libcharconv_negative.c b/libcharconv_negative.c
index 92470c8..4f35489 100644
--- a/libcharconv_negative.c
+++ b/libcharconv_negative.c
@@ -42,7 +42,8 @@ static struct {
{{UINT32_C(0x246A), UINT32_C(0x2473)}, {UINT32_C(0x24EB), UINT32_C(0x24F4)}},
{{UINT32_C(0x24B6), UINT32_C(0x24CF)}, {UINT32_C(0x1F150), UINT32_C(0x1F169)}},
{{UINT32_C(0x1F130), UINT32_C(0x1F149)}, {UINT32_C(0x1F170), UINT32_C(0x1F189)}},
- {{UINT32_C(0x2780), UINT32_C(0x2789)}, {UINT32_C(0x278A), UINT32_C(0x2793)}}
+ {{UINT32_C(0x2780), UINT32_C(0x2789)}, {UINT32_C(0x278A), UINT32_C(0x2793)}},
+ {{UINT32_C(0x2660), UINT32_C(0x2663)}, {UINT32_C(0x2664), UINT32_C(0x2667)}}
};