/* 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; }