diff options
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | convert-to-xiangqi.c | 22 | ||||
| -rw-r--r-- | libcharconv.h | 12 | ||||
| -rw-r--r-- | libcharconv_latin.c | 5 | ||||
| -rw-r--r-- | libcharconv_xiangqi_black.c | 150 | ||||
| -rw-r--r-- | libcharconv_xiangqi_red.c | 150 |
6 files changed, 344 insertions, 2 deletions
@@ -72,7 +72,8 @@ BIN =\ convert-to-ideographic-tally-marks\ convert-to-negative\ convert-to-symbols\ - convert-to-control-characters + convert-to-control-characters\ + convert-to-xiangqi LIBOBJ =\ libcharconv_decode_utf8_.o\ @@ -133,7 +134,9 @@ LIBOBJ =\ libcharconv_ideographic_tally_marks.o\ libcharconv_negative.o\ libcharconv_symbols.o\ - libcharconv_control_characters.o + libcharconv_control_characters.o\ + libcharconv_xiangqi_red.o\ + libcharconv_xiangqi_black.o LOBJ = $(LIBOBJ:.o=.lo) diff --git a/convert-to-xiangqi.c b/convert-to-xiangqi.c new file mode 100644 index 0000000..0ec1f29 --- /dev/null +++ b/convert-to-xiangqi.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-r | -b]"); + + +int +main(int argc, char *argv[]) +{ + int black = 0; + + ARGBEGIN { + case 'b': black = 1; break; + case 'r': black = 0; break; + default: + usage(); + } ARGEND; + if (argc) + usage(); + + return convert(black ? &libcharconv_xiangqi_black : &libcharconv_xiangqi_red); +} diff --git a/libcharconv.h b/libcharconv.h index b6050a9..629fd39 100644 --- a/libcharconv.h +++ b/libcharconv.h @@ -389,6 +389,18 @@ LIBCHARCONV_FUNC_(libcharconv_symbols); */ LIBCHARCONV_FUNC_(libcharconv_control_characters); +/** + * Convert characters Xiangqi pieces, with red + * as the default colour + */ +LIBCHARCONV_FUNC_(libcharconv_xiangqi_red); + +/** + * Convert characters Xiangqi pieces, with black + * as the default colour + */ +LIBCHARCONV_FUNC_(libcharconv_xiangqi_black); + #undef LIBCHARCONV_FUNC_ #endif diff --git a/libcharconv_latin.c b/libcharconv_latin.c index db60835..0b40d77 100644 --- a/libcharconv_latin.c +++ b/libcharconv_latin.c @@ -444,6 +444,11 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz c -= (uint_least32_t)UINT32_C(0x110F0) - (uint_least32_t)'0'; goto conv; + } else if (UINT32_C(0x1FA60) <= c && c <= UINT32_C(0x1FA6D)) { + /* xiangqi */ + c = (uint_least32_t)"gaehrcsGAEHRCS"[c - UINT32_C(0x1FA60)]; + goto conv; + } else { use_switch: switch (c) { diff --git a/libcharconv_xiangqi_black.c b/libcharconv_xiangqi_black.c new file mode 100644 index 0000000..e44dd13 --- /dev/null +++ b/libcharconv_xiangqi_black.c @@ -0,0 +1,150 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" +#include <string.h> + + +#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; +} diff --git a/libcharconv_xiangqi_red.c b/libcharconv_xiangqi_red.c new file mode 100644 index 0000000..d68647a --- /dev/null +++ b/libcharconv_xiangqi_red.c @@ -0,0 +1,150 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" +#include <string.h> + + +#define DEFAULT RED + +#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_red(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; +} |
