summaryrefslogtreecommitdiff
path: root/third_party/mcpc/tst
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/mcpc/tst')
-rw-r--r--third_party/mcpc/tst/.indent.pro1
-rw-r--r--third_party/mcpc/tst/CMakeLists.txt33
-rw-r--r--third_party/mcpc/tst/Makefile108
-rw-r--r--third_party/mcpc/tst/commtst.c181
-rw-r--r--third_party/mcpc/tst/commtst.h147
-rw-r--r--third_party/mcpc/tst/itst-svcalc-req-promptslist-1.json1
-rw-r--r--third_party/mcpc/tst/itst-svcalc-req-resourceslist-1.json1
-rw-r--r--third_party/mcpc/tst/itst-svcalc-req-toolslist-1.json1
-rw-r--r--third_party/mcpc/tst/itst-svcalc.c207
9 files changed, 680 insertions, 0 deletions
diff --git a/third_party/mcpc/tst/.indent.pro b/third_party/mcpc/tst/.indent.pro
new file mode 100644
index 0000000..f7bb493
--- /dev/null
+++ b/third_party/mcpc/tst/.indent.pro
@@ -0,0 +1 @@
+../.indent.pro \ No newline at end of file
diff --git a/third_party/mcpc/tst/CMakeLists.txt b/third_party/mcpc/tst/CMakeLists.txt
new file mode 100644
index 0000000..d9b5bd5
--- /dev/null
+++ b/third_party/mcpc/tst/CMakeLists.txt
@@ -0,0 +1,33 @@
+
+
+add_compile_options(/Dis_win)
+add_compile_options(/Dis_wincl)
+add_compile_options(/nologo)
+add_compile_options(/std:c17)
+add_compile_options(/DMCPC_C23PTCH_KW1)
+add_compile_options(/DMCPC_C23PTCH_CKD1)
+add_compile_options(/DMCPC_C23PTCH_UCHAR1)
+
+
+# --------------------------- Add A Test ---------------------------
+
+set (CurrTestName server1)
+
+add_executable (${CurrTestName} ${CurrTestName}.c commtst.c)
+
+target_include_directories (
+ ${CurrTestName}
+ PRIVATE ${PROJECT_SOURCE_DIR}
+ PRIVATE ${PROJECT_SOURCE_DIR}/src
+)
+
+target_link_libraries (${CurrTestName} ws2_32)
+target_link_libraries (${CurrTestName} mcpc)
+
+add_test(NAME ${CurrTestName} COMMAND ${CurrTestName})
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/server1-req-initialize-1.json
+ ${CMAKE_CURRENT_BINARY_DIR}/server1-req-initialize-1.json
+ COPYONLY
+)
diff --git a/third_party/mcpc/tst/Makefile b/third_party/mcpc/tst/Makefile
new file mode 100644
index 0000000..5951716
--- /dev/null
+++ b/third_party/mcpc/tst/Makefile
@@ -0,0 +1,108 @@
+include ../mk/step0.mk
+
+ifneq (,$(is_linux))
+ include ../mk/ccdefs-linux.mk
+endif
+ifneq (,$(is_cygwin))
+ include ../mk/ccdefs-cygwin.mk
+endif
+ifneq (,$(is_mingw))
+ include ../mk/ccdefs-mingw.mk
+endif
+ifneq (,$(is_macos))
+ include ../mk/ccdefs-macos.mk
+endif
+ifneq (,$(is_win))
+ include ../mk/ccdefs-win.mk
+endif
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+include ../mk/dbgrel.mk
+
+
+ifneq (,$(is_gcclike))
+ CFLAGS += -I../src
+endif
+ifneq (,$(is_cllike))
+ CFLAGS += /I..\src
+endif
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+default: link utst
+
+clean:
+ $(if $(is_cmd) , del *.pdb *.ilk *.o *.out *.a *.so *.dSYM *.obj *.exe *.lib *.dll *.exp *.log )
+ $(if $(is_sh) , rm -rf *.pdb *.ilk *.o *.out *.a *.so *.dSYM *.obj *.exe *.lib *.dll *.exp *.log )
+
+comp: itst-svcalc_COMP
+
+link: itst-svcalc_LINKE
+
+utst: itst-svcalc_EXEC
+
+itst: itst-svcalc_EXEC
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# itst-svcalc
+
+itst-svcalc_srcs =
+itst-svcalc_srcs += commtst.c
+itst-svcalc_srcs += itst-svcalc.c
+
+itst-svcalc_objs =
+ifneq (,$(is_gcclike))
+ itst-svcalc_objs = $(patsubst %.c,%.o,$(itst-svcalc_srcs))
+else ifneq (,$(is_cllike))
+ itst-svcalc_objs = $(patsubst %.c,%.obj,$(itst-svcalc_srcs))
+endif
+
+itst-svcalc_ldflags =
+ifneq (,$(is_unixar))
+ itst-svcalc_ldflags += ../src/libmcpc.a
+endif
+ifneq (,$(is_manual_pthread))
+ itst-svcalc_ldflags += -lpthread
+endif
+ifneq (,$(is_winlib))
+ itst-svcalc_ldflags += ws2_32.lib
+ itst-svcalc_ldflags += ..\src\mcpc.lib
+endif
+ifneq (,$(is_winld))
+ itst-svcalc_ldflags += -lws2_32
+endif
+
+
+itst-svcalc_COMP:
+ $(if $(is_gcclike) , $(CC) $(CFLAGS) $(itst-svcalc_srcs) -c )
+ $(if $(is_cllike) , $(CC) $(CFLAGS) $(itst-svcalc_srcs) /c )
+itst-svcalc_LINKE: itst-svcalc_COMP
+ $(if $(is_gcclike) , $(CC) $(itst-svcalc_objs) $(LDFLAGS) $(itst-svcalc_ldflags) -o itst-svcalc.out )
+ $(if $(is_cllike) , $(CC) $(itst-svcalc_objs) /link /out:itst-svcalc.exe $(LDFLAGS) $(itst-svcalc_ldflags))
+itst-svcalc_EXEC: itst-svcalc_LINKE
+ @ echo>>$@.stdout.log; echo>>$@.stderr.log;
+ $(if $(is_unix) , @ date>>$@.stdout.log; date>>$@.stderr.log; )
+ $(if $(is_cmd) , echo ___>>$@.stdout.log; echo ___>>$@.stderr.log; )
+ $(if $(is_pkill) , pkill itst-sv || printf "" )
+ # itst-svcalc toolslist
+ $(if $(is_dirsh) , ./itst-svcalc.out iostrm -i itst-svcalc-req-toolslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(is_cmd) , itst-svcalc.exe iostrm -i itst-svcalc-req-toolslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(and $(is_indirsh),$(is_cllike)) , ./itst-svcalc.exe iostrm -i itst-svcalc-req-toolslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(and $(is_indirsh),$(is_gcclike)) , ./itst-svcalc.out iostrm -i itst-svcalc-req-toolslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(is_valg) , valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=222 ./itst-svcalc.out iostrm -i itst-svcalc-req-toolslist-1.json 1>/dev/null 2>/dev/null )
+ # itst-svcalc promptslist
+ $(if $(is_dirsh) , ./itst-svcalc.out iostrm -i itst-svcalc-req-promptslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(is_cmd) , itst-svcalc.exe iostrm -i itst-svcalc-req-promptslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(and $(is_indirsh),$(is_cllike)) , ./itst-svcalc.exe iostrm -i itst-svcalc-req-promptslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(and $(is_indirsh),$(is_gcclike)) , ./itst-svcalc.out iostrm -i itst-svcalc-req-promptslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(is_valg) , valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=222 ./itst-svcalc.out iostrm -i itst-svcalc-req-promptslist-1.json 1>/dev/null 2>/dev/null )
+ # itst-svcalc resourceslist
+ $(if $(is_dirsh) , ./itst-svcalc.out iostrm -i itst-svcalc-req-resourceslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(is_cmd) , itst-svcalc.exe iostrm -i itst-svcalc-req-resourceslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(and $(is_indirsh),$(is_cllike)) , ./itst-svcalc.exe iostrm -i itst-svcalc-req-resourceslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(and $(is_indirsh),$(is_gcclike)) , ./itst-svcalc.out iostrm -i itst-svcalc-req-resourceslist-1.json 1>>$@.stdout.log 2>>$@.stderr.log )
+ $(if $(is_valg) , valgrind --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=222 ./itst-svcalc.out iostrm -i itst-svcalc-req-resourceslist-1.json 1>/dev/null 2>/dev/null )
+ @echo P A S S E D : $(patsubst %_EXEC,%,$@)
diff --git a/third_party/mcpc/tst/commtst.c b/third_party/mcpc/tst/commtst.c
new file mode 100644
index 0000000..a2ba8dc
--- /dev/null
+++ b/third_party/mcpc/tst/commtst.c
@@ -0,0 +1,181 @@
+#include "commtst.h"
+
+#include <stdint.h>
+
+i32_t
+fsize (FILE *strm)
+{
+ fseek (strm, 0, SEEK_SET);
+ fseek (strm, 0, SEEK_END);
+ long sz = ftell (strm);
+ assert (sz > 0);
+ fseek (strm, 0, SEEK_SET);
+ return sz;
+}
+
+void
+read_atmost (void *src, char *rbuf, const size_t nmost, size_t *nread)
+{
+#ifdef is_win
+ HANDLE *hdlp = (HANDLE *) src;
+#else
+ int *fdp = (int *) src;
+#endif
+ size_t nread_accm = 0;
+ size_t nleft = nmost;
+ while (nleft > 0)
+ {
+ ssize_t nbuffered = nmost - nleft;
+#ifdef is_win
+ ssize_t nread_cur = 0;
+ assT (ReadFile
+ (*hdlp, rbuf + nbuffered, (DWORD)nleft, (LPDWORD) (&nread_cur),
+ nullptr));
+#else
+ ssize_t nread_cur = read (*fdp, rbuf + nbuffered, nleft);
+#endif
+ if (nread_cur <= 0)
+ break;
+ nread_accm += nread_cur;
+ nleft -= nread_cur;
+ }
+ *nread = nread_accm;
+}
+
+void
+recv_atmost (
+#if is_unix
+ int csock,
+#elif is_win
+ SOCKET csock,
+#endif
+ char *rbuf, const size_t nmost, size_t *nread)
+{
+ size_t nread_accm = 0;
+ size_t nleft = nmost;
+ while (nleft > 0)
+ {
+ ssize_t nbuffered = nmost - nleft;
+ ssize_t nread_cur = recv (csock, rbuf + nbuffered, (int)nleft, 0);
+ if (nread_cur <= 0)
+ break;
+ nread_accm += nread_cur;
+ nleft -= nread_cur;
+ }
+ *nread = nread_accm;
+}
+
+i32_t
+read_u8str (const char8_t *const filename, char8_t *const destbuf)
+{
+ FILE *file;
+
+#if is_win
+ fopen_s (&file, (const char*) filename, "rb,ccs=UTF-8");
+#else
+ file = fopen ((const char*) filename, "rb");
+#endif
+ assert (file != nullptr);
+
+ i32_t fsz = fsize (file);
+
+ size_t bytes_read = fread (destbuf, 1, fsz, file);
+ assert (bytes_read > 0);
+
+ // null-terminate the buffer
+ destbuf[bytes_read] = 0;
+ // printf("File content: %s\n", destbuf);
+
+ fclose (file);
+
+ return 0;
+}
+
+i32_t
+read_u8str_sz (const char8_t *const filename, char8_t *const destbuf,
+ size_t *nread)
+{
+ FILE *file;
+
+#if is_win
+ fopen_s (&file, (const char*) filename, "rb,ccs=UTF-8");
+#else
+ file = fopen ((const char*) filename, "rb");
+#endif
+ assTcb (file != nullptr,
+ {
+ fprintf (stderr, "filename:%s\n", filename);
+ });
+
+ i32_t fsz = fsize (file);
+
+ size_t bytes_read = fread (destbuf, 1, fsz, file);
+ assert (bytes_read > 0);
+
+ // null-terminate the buffer
+ destbuf[bytes_read] = 0;
+ *nread = bytes_read;
+ // printf("File content: %s\n", destbuf);
+
+ fclose (file);
+
+ return 0;
+}
+
+void
+zero_trailing_white_char (char8_t *buf, const size_t len)
+{
+ for (size_t i = len - 1; i != 0; i--) // TODO ckd_add
+ {
+ if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == '\t' || buf[i] == ' ')
+ buf[i] = 0;
+ else
+ break;
+ }
+}
+
+void
+zero_trailing_white_char2 (char8_t *buf, size_t *len)
+{
+ for (size_t i = *len - 1; i != 0; i--) // TODO ckd_add
+ {
+ if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == '\t' || buf[i] == ' ')
+ {
+ buf[i] = 0;
+ *len -= 1;
+ }
+ else
+ break;
+ }
+}
+
+#ifdef is_unix
+FILE *
+unix_fd2strm_r (int fd)
+{
+ return fdopen (fd, "r");
+}
+#endif
+
+#ifdef is_win
+FILE *
+win_handle2strm (HANDLE h)
+{
+ int fd = _open_osfhandle ((intptr_t) h, _O_RDONLY);
+ assT (fd > 0);
+
+ FILE *file = _fdopen (fd, "r+");
+ assT (file != nullptr);
+ return file;
+}
+#endif
+
+#ifdef is_win
+int
+win_handle2fd (HANDLE h)
+{
+ int fd = _open_osfhandle ((intptr_t) h, _O_RDONLY);
+ assT (fd > 0);
+ return fd;
+}
+#endif
diff --git a/third_party/mcpc/tst/commtst.h b/third_party/mcpc/tst/commtst.h
new file mode 100644
index 0000000..49dcc93
--- /dev/null
+++ b/third_party/mcpc/tst/commtst.h
@@ -0,0 +1,147 @@
+#ifndef h_commtst
+#define h_commtst
+
+
+// clang-format off
+#ifdef is_unix
+#define _POSIX_SOURCE
+#include <ctype.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <signal.h>
+#include <spawn.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif
+
+#ifdef is_win
+
+/* # define _WINSOCKAPI_ */
+#include <fcntl.h>
+#include <stdio.h>
+#include <winsock2.h>
+/* # include <windows.h> */
+#include <io.h>
+#include <ws2tcpip.h>
+#include "commtst.h"
+
+#endif
+// clang-format on
+
+#include <mcpc/_c23_keywords.h>
+#include <mcpc/_c23_uchar.h>
+#include <ext_string.h>
+#include <ext_stdint.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ass0(f) \
+ do { \
+ int ec = (f); \
+ if (0 != ec) { \
+ fprintf(stderr, \
+ "%s:%d,ec:%d syserr:%s\n", \
+ __FILE__, \
+ __LINE__, \
+ ec, \
+ strerror(errno)); \
+ abort(); \
+ } \
+ } while (0)
+
+#define assT(f) \
+ do { \
+ if (!(f)) { \
+ fprintf(stderr, \
+ "abort@%s:%d,syserr:%s\n", \
+ __FILE__, \
+ __LINE__, \
+ strerror(errno)); \
+ abort(); \
+ } \
+ } while (0)
+
+#define assF(f) \
+ do { \
+ if ((f)) { \
+ fprintf(stderr, \
+ "abort@%s:%d,syserr:%s\n", \
+ __FILE__, \
+ __LINE__, \
+ strerror(errno)); \
+ abort(); \
+ } \
+ } while (0)
+
+#define assTcb(f, cb) \
+ do { \
+ if (!(f)) { \
+ { cb }; \
+ fprintf(stderr, "abort@%s:%d\n", __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while (0)
+
+#define BUFCAP 1024
+#define PORT 8080
+
+typedef int8_t i8_t;
+typedef uint8_t u8_t;
+typedef int16_t i16_t;
+typedef uint16_t u16_t;
+typedef int32_t i32_t;
+typedef uint32_t u32_t;
+typedef int64_t i64_t;
+typedef uint64_t u64_t;
+
+typedef char8_t ch8_t;
+
+typedef size_t sz_t;
+
+#ifdef is_win
+typedef SSIZE_T ssize_t;
+#endif
+
+void read_atmost (void *src, char *rbuf, const size_t nexact, size_t *nread);
+
+void recv_atmost (
+#ifdef is_unix
+ int csock,
+#elif defined(is_win)
+ SOCKET cosck,
+#endif
+ char *rbuf, const size_t nmost, size_t *nread);
+
+int32_t read_u8str (const char8_t * const filename, char8_t * const destbuf);
+
+int32_t read_u8str_sz (const char8_t * const filename, char8_t * const destbuf, size_t *nread);
+
+void zero_trailing_white_char (char8_t * buf, const size_t len);
+
+void zero_trailing_white_char2 (char8_t * buf, size_t *len);
+
+
+#ifdef is_unix
+FILE *unix_fd2strm_r (int fd);
+#endif
+
+#ifdef is_win
+FILE *win_handle2strm (HANDLE h);
+#endif
+
+#ifdef is_win
+int win_handle2fd (HANDLE h);
+#endif
+
+
+#endif
diff --git a/third_party/mcpc/tst/itst-svcalc-req-promptslist-1.json b/third_party/mcpc/tst/itst-svcalc-req-promptslist-1.json
new file mode 100644
index 0000000..2431074
--- /dev/null
+++ b/third_party/mcpc/tst/itst-svcalc-req-promptslist-1.json
@@ -0,0 +1 @@
+{"jsonrpc": "2.0", "method": "initialize", "params": {"clientInfo": {"name": "Llama Agent", "version": "0.1"}, "protocolVersion": "2024-11-05", "capabilities": { "tools": { "subscribe": true, "listChanged": true }, "resource": { "subscribe": true, "listChanged": true } }}, "id": 1}{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}, "id": 8899}{"id":123,"method":"prompts/list","params":[{"obfsarg":"{\"'}}"}]}
diff --git a/third_party/mcpc/tst/itst-svcalc-req-resourceslist-1.json b/third_party/mcpc/tst/itst-svcalc-req-resourceslist-1.json
new file mode 100644
index 0000000..cf23347
--- /dev/null
+++ b/third_party/mcpc/tst/itst-svcalc-req-resourceslist-1.json
@@ -0,0 +1 @@
+{"jsonrpc": "2.0", "method": "initialize", "params": {"clientInfo": {"name": "Llama Agent", "version": "0.1"}, "protocolVersion": "2024-11-05", "capabilities": { "tools": { "subscribe": true, "listChanged": true }, "resource": { "subscribe": true, "listChanged": true } }}, "id": 1}{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}, "id": 8899}{"id":123,"method":"resources/list","params":[{"obfsarg":"{\"'}}"}]}
diff --git a/third_party/mcpc/tst/itst-svcalc-req-toolslist-1.json b/third_party/mcpc/tst/itst-svcalc-req-toolslist-1.json
new file mode 100644
index 0000000..97be6cf
--- /dev/null
+++ b/third_party/mcpc/tst/itst-svcalc-req-toolslist-1.json
@@ -0,0 +1 @@
+{"jsonrpc": "2.0", "method": "initialize", "params": {"clientInfo": {"name": "Llama Agent", "version": "0.1"}, "protocolVersion": "2024-11-05", "capabilities": { "tools": { "subscribe": true, "listChanged": true }, "resource": { "subscribe": true, "listChanged": true } }}, "id": 1}{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}, "id": 8899}{"id":123,"method":"tools/list","params":[{"obfsarg":"{\"'}}"}]}
diff --git a/third_party/mcpc/tst/itst-svcalc.c b/third_party/mcpc/tst/itst-svcalc.c
new file mode 100644
index 0000000..3932991
--- /dev/null
+++ b/third_party/mcpc/tst/itst-svcalc.c
@@ -0,0 +1,207 @@
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <mcpc/_c23_keywords.h>
+#include <mcpc/mcpc.h>
+
+#include <ext_string.h>
+
+typedef int8_t i8_t;
+typedef uint8_t u8_t;
+typedef int16_t i16_t;
+typedef uint16_t u16_t;
+typedef int32_t i32_t;
+typedef uint32_t u32_t;
+typedef int64_t i64_t;
+typedef uint64_t u64_t;
+
+static void
+cb_calc (const mcpc_tool_t *tool, mcpc_ucbr_t *ucbr)
+{
+ i32_t a = 0;
+ i32_t b = 0;
+ char8_t op[64];
+ i32_t res = 0;
+
+ assert (0 == mcpc_tool_get_tpropval_i32 (tool, u8c1 ("a"), &a));
+ assert (0 == mcpc_tool_get_tpropval_i32 (tool, u8c1 ("b"), &b));
+ assert (0 == mcpc_tool_get_tpropval_u8str (tool, u8c1 ("op"), op, sizeof (op), nullptr));
+
+ if (false)
+ ;
+ else if (u8streq (op, u8c1 ("+")))
+ {
+ res = a + b;
+ }
+ else if (u8streq (op, u8c1 ("+")))
+ {
+ res = a + b;
+ }
+ else if (u8streq (op, u8c1 ("-")))
+ {
+ res = a - b;
+ }
+ else if (u8streq (op, u8c1 ("*")))
+ {
+ res = a * b;
+ }
+ else if (u8streq (op, u8c1 ("times")))
+ {
+ res = a * b;
+ }
+ else if (u8streq (op, u8c1 ("/")))
+ {
+ res = a / b;
+ }
+ else if (u8streq (op, u8c1 ("div")))
+ {
+ res = a / b;
+ }
+ else
+ {
+ mcpc_ucbr_toolcall_add_errmsg_printf8 (ucbr, u8c1 ("not matching \"any\" operator:%s"), op);
+ return;
+ }
+
+ mcpc_ucbr_toolcall_add_text_printf8 (ucbr, u8c1 ("%d"), res);
+}
+
+mcpc_tool_t *
+new_tool_calc ()
+{
+ const char8_t *name = u8c1 ("calc");
+ const char8_t *desc = u8c1 ("simple calculator");
+ mcpc_tool_t *tool = mcpc_tool_new2 (name, desc);
+
+ {
+ const char8_t *name = u8c1 ("a");
+ const mcpc_anytype_t type = MCPC_I32;
+ const char8_t *desc = u8c1 ("the first number(\"a\") to calculate");
+ mcpc_toolprop_t *prop = mcpc_toolprop_new2 (name, desc, type);
+ mcpc_tool_add_toolprop (tool, prop);
+ }
+ {
+ const char8_t *name = u8c1 ("b");
+ const mcpc_anytype_t type = MCPC_I32;
+ const char8_t *desc = u8c1 ("the second number to calculate");
+ mcpc_toolprop_t *prop = mcpc_toolprop_new2 (name, desc, type);
+ mcpc_tool_add_toolprop (tool, prop);
+ }
+ {
+ const char8_t *name = u8c1 ("op");
+ const mcpc_anytype_t type = MCPC_U8STR;
+ const char8_t *desc = //
+ u8c1 ("the calculating operator, available values " "are: \"+\",'-',\"*\",'/'");
+ mcpc_toolprop_t *prop = mcpc_toolprop_new2 (name, desc, type);
+ mcpc_tool_add_toolprop (tool, prop);
+ }
+
+ mcpc_tool_set_call_cb (tool, &cb_calc);
+
+ return tool;
+}
+
+int
+main_iostrm (int argc, const char *argv[])
+{
+ u8_t in_src = 0; // 1stdin 2file
+ char in_fpath[100];
+
+ for (int i = 2; i < argc; i++)
+ {
+ const char8_t *curr_arg = (const char8_t *) argv[i];
+ const char8_t *nex_arg = nullptr;
+ if (i < argc - 1)
+ nex_arg = (const char8_t *) argv[i + 1];
+ if (nex_arg != nullptr)
+ {
+ if (u8streq (curr_arg, u8c1 ("-i")))
+ {
+ if (u8streq (nex_arg, u8c1 ("-")))
+ {
+ in_src = 1;
+ }
+ else if (beg_with_alph ((const char8_t *) nex_arg))
+ {
+ // TODO nonascii filename?
+ /* memcpy (in_fpath, nex_arg, strlen (nex_arg)); */
+ strcpy (in_fpath, (const char *) nex_arg);
+ in_src = 2;
+ }
+ }
+ }
+ }
+
+ assert (in_src);
+
+ FILE *in_stream = nullptr;
+ switch (in_src)
+ {
+ case 1:
+ in_stream = stdin;
+ break;
+ case 2:
+ in_stream = fopen (in_fpath, "r");
+ if (!in_stream)
+ {
+ fprintf (stdout, "file:%s, err:%s", in_fpath, strerror (errno));
+ }
+ break;
+ }
+ assert (in_stream);
+
+ mcpc_server_t *server = mcpc_server_new_iostrm (in_stream, stdout);
+ mcpc_server_capa_enable_prmt (server);
+ mcpc_server_capa_enable_tool (server);
+ mcpc_server_capa_enable_rsc (server);
+ mcpc_server_capa_enable_complt (server);
+
+ mcpc_tool_t *tool = new_tool_calc ();
+ assert (0 == mcpc_server_add_tool (server, tool));
+
+ mcpc_errcode_t ec = mcpc_server_start (server);
+
+ mcpc_server_close (server);
+ fclose (in_stream);
+
+ return ec;
+}
+
+int
+main_tcp (int argc, const char *argv[])
+{
+ mcpc_server_t *server = mcpc_server_new_tcp ();
+ mcpc_server_capa_enable_prmt (server);
+ mcpc_server_capa_enable_tool (server);
+ mcpc_server_capa_enable_rsc (server);
+ mcpc_server_capa_enable_complt (server);
+
+ mcpc_tool_t *tool = new_tool_calc ();
+ assert (0 == mcpc_server_add_tool (server, tool));
+
+ mcpc_errcode_t ec = mcpc_server_start (server);
+
+ mcpc_server_close (server);
+ return ec;
+}
+
+int
+main (int argc, const char *argv[])
+{
+ assert (argc >= 2);
+ bool as_iostrm = strcmp (argv[1], "iostrm") == 0;
+ bool as_tcp = strcmp (argv[1], "tcp") == 0;
+ assert (as_iostrm || as_tcp);
+ // bool as_iostrm = false;
+ // bool as_tcp = true;
+ if (as_tcp)
+ return main_tcp (argc, argv);
+ if (as_iostrm)
+ return main_iostrm (argc, argv);
+}