From cba78a7ec0f47ad4d9f1386468dd789c31350e9d Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sat, 20 Aug 2016 05:17:47 +0000 Subject: [PATCH] started adding console primitives --- stix/kernel/test-014.st | 75 ++++++++++++ stix/lib/Makefile.am | 2 +- stix/lib/Makefile.in | 2 +- stix/lib/mod-con.c | 260 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 337 insertions(+), 2 deletions(-) create mode 100644 stix/kernel/test-014.st create mode 100644 stix/lib/mod-con.c diff --git a/stix/kernel/test-014.st b/stix/kernel/test-014.st new file mode 100644 index 0000000..3285020 --- /dev/null +++ b/stix/kernel/test-014.st @@ -0,0 +1,75 @@ + +#include 'Stix.st'. + +################################################################# +## MAIN +################################################################# + +## TODO: use #define to define a class or use #class to define a class. +## use #extend to extend a class +## using #class for both feels confusing. + +#extend Apex +{ + +} + +#extend SmallInteger +{ + #method getTrue: anInteger + { + ^anInteger + 9999. + } + + #method inc + { + ^self + 1. + } +} + +#class TestObject(Object) +{ + #dcl(#class) Q R. + #dcl(#classinst) a1 a2. + + #method test999 + { + ^self.Q + } +} + +#class B.TestObject(Object) +{ + #dcl(#class) Q R. + #dcl(#classinst) a1 a2. + + #method test000 + { + ^self.Q + } +} + +#pooldic ABC +{ + #KKK := 20. +} + + +#class MyObject(TestObject) +{ + #method(#class) main + { + | v1 v2 | + System logNl: 'START OF MAIN'. + + v1 := Console output. + + v1 write: S'hello, 월드 이거 좋지 않니\n'. + v1 write: S'하하하하하하하하 좋아좋아 可愛くってしょうがない(^o^) ほのかちゃん、しおりちゃん元気そうだね! 久しぶりに見た。しおりちゃんどうしたのかな?좋아 하라하하\n'. + v1 close. + + System logNl: S'\0\0\0END OF MAIN\0AB\0\0\0C\0\0\0'. + } + +} + diff --git a/stix/lib/Makefile.am b/stix/lib/Makefile.am index ed76fad..b6081d0 100644 --- a/stix/lib/Makefile.am +++ b/stix/lib/Makefile.am @@ -95,7 +95,7 @@ libstix_snd_la_LIBADD = $(LIBADD_MOD_COMMON) libstix_con_la_SOURCES = mod-con.c mod-con.h libstix_con_la_CPPFLAGS = $(CPPFLAGS_MOD_COMMON) libstix_con_la_LDFLAGS = $(LDFLAGS_MOD_COMMON) -libstix_con_la_LIBADD = $(LIBADD_MOD_COMMON) +libstix_con_la_LIBADD = $(LIBADD_MOD_COMMON) -ltermcap endif diff --git a/stix/lib/Makefile.in b/stix/lib/Makefile.in index b4ea68d..a6cc669 100644 --- a/stix/lib/Makefile.in +++ b/stix/lib/Makefile.in @@ -481,7 +481,7 @@ stix_LDADD = $(LIBADD_LIB_COMMON) -lstix #-ldyncall_s @ENABLE_STATIC_MODULE_FALSE@libstix_con_la_SOURCES = mod-con.c mod-con.h @ENABLE_STATIC_MODULE_FALSE@libstix_con_la_CPPFLAGS = $(CPPFLAGS_MOD_COMMON) @ENABLE_STATIC_MODULE_FALSE@libstix_con_la_LDFLAGS = $(LDFLAGS_MOD_COMMON) -@ENABLE_STATIC_MODULE_FALSE@libstix_con_la_LIBADD = $(LIBADD_MOD_COMMON) +@ENABLE_STATIC_MODULE_FALSE@libstix_con_la_LIBADD = $(LIBADD_MOD_COMMON) -ltermcap all: stix-cfg.h $(MAKE) $(AM_MAKEFLAGS) all-am diff --git a/stix/lib/mod-con.c b/stix/lib/mod-con.c new file mode 100644 index 0000000..181f2a5 --- /dev/null +++ b/stix/lib/mod-con.c @@ -0,0 +1,260 @@ +/* + * $Id$ + * + Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "mod-con.h" +#include + +#include "stix-prv.h" /* TODO: remove this header after refactoring it */ + +#include +#include + +#include /* getenv */ + +#include +#include + +#include + +typedef struct console_t console_t; +struct console_t +{ + int fd; + int fd_opened; + char* cup; + char* clear; +}; +/* ------------------------------------------------------------------------ */ + +static int prim_open (stix_t* stix, stix_ooi_t nargs) +{ +#if defined(_WIN32) + HANDLE h; + stix_ooi_t immv; + + h = GetStdHandle(STD_INPUT_HANDLE); + if (h == INVALID_HANDLE_VALUE) return 0; + if (h == NULL) + { + } + + imm = stix_makeimm (stix, h); + if (imm <= -1) + { + /* error */ + } + + rsrc = stix_makersrc (stix, h); + +#else + + console_t* con; + int err; + char* term; + + con = stix_callocmem (stix, STIX_SIZEOF(*con)); + if (!con) return 0; + + if (isatty(1)) + { + con->fd = 1; + } + else + { + con->fd = open ("/dev/tty", O_RDWR, 0); + if (con->fd == -1) + { + /* TODO: failed to open /dev/stdout */ + stix_freemem (stix, con); + return 0; + } + + con->fd_opened = 1; + } + + term = getenv ("TERM"); + if (term && setupterm (term, con->fd, &err) == OK) + { + } + + con->cup = tigetstr ("cup"); /* TODO: error check */ + con->clear = tigetstr ("clear"); + +#if 0 + { + const char* cup, * clear; + struct winsize wsz; + + cup = tigetstr ("cup"); + clear = tigetstr ("clear"); + ioctl (fd, TIOCGWINSZ, &wsz); + + write (fd, clear, strlen(clear)); + /*write (fd, tparm (cup, wsz.ws_row - 1, 0), strlen(tparm (cup, wsz.ws_row - 1, 0)));*/ + write (fd, tiparm (cup, 0, 0), strlen(tiparm (cup, 0, 0))); + } +#endif + +#endif + + STIX_STACK_SETRET (stix, nargs, STIX_SMOOI_TO_OOP((stix_oow_t)con)); + return 1; +} + +static int prim_close (stix_t* stix, stix_ooi_t nargs) +{ +#if defined(_WIN32) + HANDLE h; + + h = STIX_STACK_GETARG (stix, nargs, 0); +#else +#endif + console_t* con; + + con = STIX_OOP_TO_SMOOI(STIX_STACK_GETARG (stix, nargs, 0)); + /* TODO: sanity check */ + + if (con->fd_opened) close (con->fd); + + STIX_STACK_SETRETTORCV (stix, nargs); + return 1; +} + +static int prim_write (stix_t* stix, stix_ooi_t nargs) +{ + console_t* con; + stix_oop_char_t oomsg; + + stix_oow_t ucspos, ucsrem, ucslen, bcslen; + stix_bch_t bcs[1024]; + int n; + + con = STIX_OOP_TO_SMOOI(STIX_STACK_GETARG (stix, nargs, 0)); + oomsg = (stix_oop_char_t)STIX_STACK_GETARG (stix, nargs, 1); + + if (STIX_CLASSOF(stix,oomsg) != stix->_string) + { +/* TODO: invalid message */ + return 0; + } + + ucspos = 0; + ucsrem = STIX_OBJ_GET_SIZE(oomsg); + while (ucsrem > 0) + { + ucslen = ucsrem; + bcslen = STIX_COUNTOF(bcs); + if ((n = stix_ucstoutf8 (&oomsg->slot[ucspos], &ucslen, bcs, &bcslen)) <= -1) + { + if (n != -2 || ucslen <= 0) + { + stix_seterrnum (stix, STIX_EECERR); + return -1; + } + } + + write (con->fd, bcs, bcslen); /* TODO: error handling */ +/* TODO: abort looping for async processing???? */ + ucspos += ucslen; + ucsrem -= ucslen; + } + + STIX_STACK_SETRETTORCV (stix, nargs); /* TODO: change return code */ + return 1; +} + +static int prim_setcursor (stix_t* stix, stix_ooi_t nargs) +{ + console_t* con; + stix_ooi_t x, y; + char* cup; + + con = STIX_OOP_TO_SMOOI(STIX_STACK_GETARG(stix, nargs, 0)); + point = STIX_OOP_TO_SMOOI(STIX_STACK_GETARG(stix, nargs, 1)); + + cup = tiparm (con->cup, point->slot[0], point->slot[1]); + write (con->fd, cup, strlen(cup)); /* TODO: error check */ + free (cup); + return 1; +} + +/* ------------------------------------------------------------------------ */ + +typedef struct fnctab_t fnctab_t; +struct fnctab_t +{ + const stix_bch_t* name; + stix_prim_impl_t handler; +}; + +static fnctab_t fnctab[] = +{ + { "close", prim_close }, + { "open", prim_open }, + { "setcursor", prim_setcursor }, + { "write", prim_write }, +}; + +/* ------------------------------------------------------------------------ */ + +static stix_prim_impl_t query (stix_t* stix, stix_prim_mod_t* mod, const stix_ooch_t* name) +{ + int left, right, mid, n; + + left = 0; right = STIX_COUNTOF(fnctab) - 1; + + while (left <= right) + { + mid = (left + right) / 2; + + n = stix_compoocbcstr (name, fnctab[mid].name); + if (n < 0) right = mid - 1; + else if (n > 0) left = mid + 1; + else + { + return fnctab[mid].handler; + } + } + + stix->errnum = STIX_ENOENT; + return STIX_NULL; +} + + +static void unload (stix_t* stix, stix_prim_mod_t* mod) +{ + /* TODO: close all open handle?? */ +} + + +int stix_prim_mod_con (stix_t* stix, stix_prim_mod_t* mod) +{ + mod->query = query; + mod->unload = unload; + mod->ctx = STIX_NULL; + return 0; +}