aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--convert-to-xiangqi.c22
-rw-r--r--libcharconv.h12
-rw-r--r--libcharconv_latin.c5
-rw-r--r--libcharconv_xiangqi_black.c150
-rw-r--r--libcharconv_xiangqi_red.c150
6 files changed, 344 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 41eea28..c11b562 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
+}