summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-01-05 12:22:34 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-01-05 12:22:34 +0800
commit306ae489376906fe06e7abcfa119aeba3cf1095c (patch)
tree0c9abf8cb74894f18d205efd8ca76605aba12386
parent17c4b2bd5db1169e22c9adca2d86559a1ed03f5c (diff)
downloadpttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.tar
pttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.tar.gz
pttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.tar.bz2
pttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.tar.lz
pttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.tar.xz
pttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.tar.zst
pttbbs-306ae489376906fe06e7abcfa119aeba3cf1095c.zip
- io: add more control API
- bbslua: enable system break git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3788 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--include/proto.h3
-rw-r--r--mbbsd/bbslua.c126
-rw-r--r--mbbsd/io.c48
3 files changed, 172 insertions, 5 deletions
diff --git a/include/proto.h b/include/proto.h
index a5371e25..e796f81d 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -333,6 +333,8 @@ void set_converting_type(int which);
int getdata(int line, int col, const char *prompt, char *buf, int len, int echo);
int igetch(void);
int wait_input(float f, int flDoRefresh);
+int peek_input(float f, int c);
+void drop_input(void);
int getdata_str(int line, int col, const char *prompt, char *buf, int len, int echo, const char *defaultstr);
int getdata_buf(int line, int col, const char *prompt, char *buf, int len, int echo);
void add_io(int fd, int timeout);
@@ -340,6 +342,7 @@ void oflush(void);
int oldgetdata(int line, int col, const char *prompt, char *buf, int len, int echo);
void output(const char *s, int len);
int num_in_buf(void);
+int input_isfull();
int ochar(int c);
/* kaede */
diff --git a/mbbsd/bbslua.c b/mbbsd/bbslua.c
index 082bc257..2a94ecd9 100644
--- a/mbbsd/bbslua.c
+++ b/mbbsd/bbslua.c
@@ -8,7 +8,8 @@
// TODO:
// 1. add quick key/val conversion
// 2. add key values (UP/DOWN/...)
-// 3. remove i/o libraries
+// 3. remove i/o libraries [done]
+// 4. add system break key (Ctrl-C?)
//////////////////////////////////////////////////////////////////////////
#include "bbs.h"
@@ -26,6 +27,11 @@
#define BLAPI_PROTO int
//////////////////////////////////////////////////////////////////////////
+// GLOBAL VARIABLES
+//////////////////////////////////////////////////////////////////////////
+static int abortBBSLua = 0;
+
+//////////////////////////////////////////////////////////////////////////
// BBSLUA API IMPLEMENTATION
//////////////////////////////////////////////////////////////////////////
@@ -101,14 +107,53 @@ bl_addstr(lua_State* L)
return 0;
}
+void
+bl_k2s(lua_State* L, int v)
+{
+ if (v <= 0)
+ lua_pushnil(L);
+ else if (v == KEY_TAB)
+ lua_pushstring(L, "TAB");
+ else if (v == '\b' || v == 0x7F)
+ lua_pushstring(L, "BS");
+ else if (v == '\n')
+ lua_pushstring(L, "ENTER");
+ else if (v < ' ')
+ lua_pushfstring(L, "^%c", v-1+'A');
+ else if (v < 0x100)
+ lua_pushfstring(L, "%c", v);
+ else if (v >= KEY_F1 && v <= KEY_F12)
+ lua_pushfstring(L, "F%d", v - KEY_F1 +1);
+ else switch(v)
+ {
+ case KEY_UP: lua_pushstring(L, "UP"); break;
+ case KEY_DOWN: lua_pushstring(L, "DOWN"); break;
+ case KEY_RIGHT: lua_pushstring(L, "RIGHT"); break;
+ case KEY_LEFT: lua_pushstring(L, "LEFT"); break;
+ case KEY_HOME: lua_pushstring(L, "HOME"); break;
+ case KEY_END: lua_pushstring(L, "END"); break;
+ case KEY_INS: lua_pushstring(L, "INS"); break;
+ case KEY_DEL: lua_pushstring(L, "DEL"); break;
+ case KEY_PGUP: lua_pushstring(L, "PGUP"); break;
+ case KEY_PGDN: lua_pushstring(L, "PGDN"); break;
+ default: lua_pushnil(L); break;
+ }
+}
+
BLAPI_PROTO
bl_igetch(lua_State* L)
{
int c = igetch();
- lua_pushinteger(L, c);
+ if (c == Ctrl('C'))
+ {
+ abortBBSLua = 1;
+ return lua_yield(L, 0);
+ }
+ bl_k2s(L, c);
return 1;
}
+
BLAPI_PROTO
bl_getdata(lua_State* L)
{
@@ -127,6 +172,7 @@ bl_getdata(lua_State* L)
if (len >= sizeof(buf))
len = sizeof(buf)-1;
+ // TODO process Ctrl-C here
getyx(&y, &x);
len = getdata(y, x, NULL, buf, len, echo);
if (len)
@@ -143,6 +189,11 @@ bl_vmsg(lua_State* L)
s = lua_tostring(L, 1);
n = vmsg(s);
+ if (n == Ctrl('C'))
+ {
+ abortBBSLua = 1;
+ return lua_yield(L, 0);
+ }
lua_pushinteger(L, n);
return 1;
}
@@ -161,6 +212,26 @@ bl_stand_title(lua_State* L)
return 0;
}
+BLAPI_PROTO
+bl_ansi_color(lua_State *L)
+{
+ char buf[PATHLEN] = ESC_STR "[";
+ char *p = buf + strlen(buf);
+ int i = 1;
+ int n = lua_gettop(L);
+ if (n >= 10) n = 10;
+ for (i = 1; i <= n; i++)
+ {
+ if (i > 1) *p++ = ';';
+ sprintf(p, "%d", (int)lua_tointeger(L, i));
+ p += strlen(p);
+ }
+ *p++ = 'm';
+ *p = 0;
+ lua_pushstring(L, buf);
+ return 1;
+}
+
//////////////////////////////////////////////////////////////////////////
// BBSLUA LIBRARY
//////////////////////////////////////////////////////////////////////////
@@ -186,6 +257,8 @@ static const struct luaL_reg lib_bbslua [] = {
{ "vmsg", bl_vmsg },
{ "pause", bl_vmsg },
{ "stand_title",bl_stand_title },
+ /* ANSI helpers */
+ { "ANSI_COLOR", bl_ansi_color },
{ NULL, NULL},
};
@@ -213,25 +286,68 @@ LUALIB_API void myluaL_openlibs (lua_State *L) {
}
}
+static void
+bbsluaRegConst(lua_State *L, const char *globName)
+{
+ lua_getglobal(L, globName);
+
+ lua_pushstring(L, "ESC"); lua_pushstring(L, ESC_STR);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "ANSI_RESET"); lua_pushstring(L, ANSI_RESET);
+ lua_settable(L, -3);
+
+}
+
+static void
+bbsluaHook(lua_State *L, lua_Debug* ar)
+{
+ // vmsg("bbslua HOOK!");
+ if (ar->event == LUA_HOOKCOUNT)
+ lua_yield(L, 0);
+}
int
bbslua(const char *fpath)
{
int r = 0;
lua_State *L = lua_open();
+
+ abortBBSLua = 0;
myluaL_openlibs(L);
- luaL_openlib(L, "bbs", lib_bbslua, 0);
+ luaL_openlib(L, "bbs", lib_bbslua, 0);
+ bbsluaRegConst(L, "bbs");
grayout(0, b_lines, GRAYOUT_DARK);
move(b_lines, 0); clrtoeol();
outs("Loading BBS-Lua " BBSLUA_VERSION_STR " ..."); refresh();
- r = luaL_dofile(L, fpath);
+ if ((r = luaL_loadfile(L, fpath)) == 0)
+ {
+ // ready for running
+ lua_sethook(L, bbsluaHook, LUA_MASKCOUNT, 100 );
+
+ while (!abortBBSLua && lua_resume(L, 0) == LUA_YIELD)
+ {
+ if (input_isfull())
+ drop_input();
+
+ refresh();
+
+ // check if input key is system break key.
+ if (peek_input(0.1, Ctrl('C')))
+ {
+ drop_input();
+ abortBBSLua = 1;
+ break;
+ }
+ }
+ }
lua_close(L);
grayout(0, b_lines, GRAYOUT_DARK);
move(b_lines, 0); clrtoeol();
- vmsgf("BBS-Lua: %s", r ? "FAILED" : "OK");
+ vmsgf("BBS-Lua: %s", abortBBSLua ? "USER ABORT" : r ? "FAILED" : "OK");
clear();
return 0;
diff --git a/mbbsd/io.c b/mbbsd/io.c
index 8cf3999c..030509e7 100644
--- a/mbbsd/io.c
+++ b/mbbsd/io.c
@@ -168,6 +168,12 @@ num_in_buf(void)
return ibufsize - icurrchar;
}
+int
+input_isfull(void)
+{
+ return ibufsize >= IBUFSIZE;
+}
+
/*
* dogetch() is not reentrant-safe. SIGUSR[12] might happen at any time, and
* dogetch() might be called again, and then ibufsize/icurrchar/inbuf might
@@ -236,6 +242,17 @@ dogetch(void)
if(len > 0)
len = input_wrapper(inbuf, len);
#endif
+#ifdef DBG_OUTRPT
+ // if (0)
+ {
+ static char xbuf[128];
+ sprintf(xbuf, ESC_STR "[s" ESC_STR "[2;1H [%ld] "
+ ESC_STR "[u", len);
+ write(1, xbuf, strlen(xbuf));
+ fsync(1);
+ }
+#endif // DBG_OUTRPT
+
} while (len <= 0);
ibufsize = len;
@@ -669,6 +686,37 @@ wait_input(float f, int flDoRefresh)
return 1;
}
+void
+drop_input(void)
+{
+ icurrchar = ibufsize = 0;
+}
+
+int
+peek_input(float f, int c)
+{
+ int i = 0;
+ assert (c > 0 && c < ' '); // only ^x keys are safe to be detected.
+ // other keys may fall into escape sequence.
+
+ if (wait_input(f, 0) && (IBUFSIZE > ibufsize))
+ {
+ int len = tty_read(inbuf + ibufsize, IBUFSIZE - ibufsize);
+#ifdef CONVERT
+ if(len > 0)
+ len = input_wrapper(inbuf+ibufsize, len);
+#endif
+ if (len > 0)
+ ibufsize += len;
+ }
+ for (i = icurrchar; i < ibufsize; i++)
+ {
+ if (inbuf[i] == c)
+ return 1;
+ }
+ return 0;
+}
+
#ifdef DBCSAWARE