/* See LICENSE file for copyright and license details. */ #include "lib-common.h" #include #define DEFAULT BLACK #define RED UINT32_C(0x1FA60) #define BLACK UINT32_C(0x1FA67) #define OTHER (RED ^ BLACK ^ DEFAULT) #define GENERAL 0u #define MANDARIN 1u #define ELEPHANT 2u #define HORSE 3u #define CHARIOT 4u #define CANNON 5u #define SOLDIER 6u static struct { uint_least32_t cp; const char *s; } symbols[] = { {DEFAULT + GENERAL, "1"}, {DEFAULT + MANDARIN, "2"}, {DEFAULT + ELEPHANT, "3"}, {DEFAULT + HORSE, "4"}, {DEFAULT + CHARIOT, "5"}, {DEFAULT + CANNON, "6"}, {DEFAULT + SOLDIER, "7"}, {BLACK + GENERAL, "將"}, {BLACK + GENERAL, "将"}, {RED + GENERAL, "帥"}, {RED + GENERAL, "帅"}, {BLACK + GENERAL, "general"}, {BLACK + GENERAL, "king"}, {DEFAULT + GENERAL, "marshal"}, {OTHER + GENERAL, "MARSHAL"}, {BLACK + MANDARIN, "士"}, {RED + MANDARIN, "仕"}, {DEFAULT + MANDARIN, "advisor"}, {DEFAULT + MANDARIN, "guard"}, {DEFAULT + MANDARIN, "assistant"}, {DEFAULT + MANDARIN, "mandarin"}, {DEFAULT + MANDARIN, "warrior"}, {DEFAULT + MANDARIN, "scholar"}, {DEFAULT + MANDARIN, "guardian"}, {OTHER + MANDARIN, "ADVISOR"}, {OTHER + MANDARIN, "GUARD"}, {OTHER + MANDARIN, "ASSISTANT"}, {OTHER + MANDARIN, "MANDARIN"}, {OTHER + MANDARIN, "WARRIOR"}, {OTHER + MANDARIN, "SCHOLAR"}, {OTHER + MANDARIN, "GUARDIAN"}, {BLACK + MANDARIN, "gentleman"}, {BLACK + MANDARIN, "officer"}, {RED + MANDARIN, "official"}, {BLACK + ELEPHANT, "象"}, {RED + ELEPHANT, "相"}, {BLACK + ELEPHANT, "elephant"}, {DEFAULT + ELEPHANT, "bishop"}, {OTHER + ELEPHANT, "BISHOP"}, {RED + ELEPHANT, "minister"}, {BLACK + HORSE, "馬"}, {RED + HORSE, "傌"}, {DEFAULT + HORSE, "horse"}, {DEFAULT + HORSE, "knight"}, {OTHER + HORSE, "HORSE"}, {OTHER + HORSE, "KNIGHT"}, {BLACK + CHARIOT, "車"}, {RED + CHARIOT, "俥"}, {DEFAULT + CHARIOT, "车"}, {DEFAULT + CHARIOT, "chariot"}, {DEFAULT + CHARIOT, "rook"}, {DEFAULT + CHARIOT, "car"}, {OTHER + CHARIOT, "CHARIOT"}, {OTHER + CHARIOT, "ROOK"}, {OTHER + CHARIOT, "CAR"}, {BLACK + CANNON, "砲"}, {RED + CANNON, "炮"}, {BLACK + CANNON, "catapult"}, {RED + CANNON, "cannon"}, {BLACK + SOLDIER, "卒"}, {RED + SOLDIER, "兵"}, {BLACK + SOLDIER, "pawn"}, {BLACK + SOLDIER, "private"}, {RED + SOLDIER, "soldier"}, {DEFAULT + CHARIOT, "x"}, {DEFAULT + MANDARIN, "m"}, {DEFAULT + MANDARIN, "a"}, {DEFAULT + CANNON, "c"}, {DEFAULT + CHARIOT, "r"}, {DEFAULT + ELEPHANT, "e"}, {DEFAULT + GENERAL, "g"}, {DEFAULT + HORSE, "h"}, {DEFAULT + SOLDIER, "s"}, {OTHER + CHARIOT, "X"}, {OTHER + MANDARIN, "M"}, {OTHER + MANDARIN, "A"}, {OTHER + CANNON, "C"}, {OTHER + CHARIOT, "R"}, {OTHER + ELEPHANT, "E"}, {OTHER + GENERAL, "G"}, {OTHER + HORSE, "H"}, {OTHER + SOLDIER, "S"} }; enum libcharconv_result libcharconv_xiangqi_black(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) { size_t i, len, found, found_len; int indeterminate; *n = 0; for (; slen; s++, slen--, ++*n) { indeterminate = 0; found = SIZE_MAX; found_len = 0u; for (i = 0u; i < sizeof(symbols) / sizeof(*symbols); i++) { len = strlen(symbols[i].s); if (strncmp(s, symbols[i].s, len < slen ? len : slen)) continue; if (slen < len) { indeterminate = 1; continue; } if (len > found_len) { found = i; found_len = len; } } if (found_len) goto conv; if (*n) goto no_conv; if (indeterminate) return LIBCHARCONV_INDETERMINATE; } no_conv: return LIBCHARCONV_NO_CONVERT; conv: if (*n) goto no_conv; if (*ncp) *cp = symbols[found].cp; *n += found_len; *ncp = 1u; return indeterminate ? LIBCHARCONV_CONVERT_IF_END : LIBCHARCONV_CONVERTED; }