ref: 553c8b384de1e6afd0463eecbf812a39a8071dcf
parent: 6acb1876c6aff7dc67dabc11c353bdda967a3504
author: telephil9 <telephil9@gmail.com>
date: Tue Oct 27 15:55:04 EDT 2020
Initial plumb module implementation New module to export libplumb functions. Currently implemented are: plumbopen, plumbsendtext, plumbrecv and eplumb. The eplumb() function is exported through the event module. For this to work, plumb.msg() allows for converting an Event.v value to a Plumbmsg pointer.
--- a/event.c
+++ b/event.c
@@ -5,6 +5,7 @@
#include <draw.h>
#include <event.h>
#include <keyboard.h>
+#include <plumb.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
@@ -60,6 +61,8 @@
lua_pushinteger(L, ev.mouse.msec);
lua_setfield(L, -2, "msec");
lua_setfield(L, -2, "mouse");
+ lua_pushlightuserdata(L, ev.v);
+ lua_setfield(L, -2, "v");
return 2;
}
@@ -175,8 +178,22 @@
else
lua_pushnil(L);
return 1;
-}
+}
+static int
+lplumb(lua_State *L)
+{
+ int key, ret;
+ char *port;
+
+ key = luaL_checkinteger(L, 1);
+ port = luaL_checkstring(L, 2);
+ ret = eplumb(key, port);
+ lua_pushinteger(L, ret);
+ return 1;
+}
+
+
static const struct luaL_Reg libevent [] = {
{ "init", leinit },
{ "event", levent },
@@ -187,6 +204,7 @@
{ "menuhit", lmenuhit },
{ "moveto", lmoveto },
{ "enter", lenter },
+ { "plumb", lplumb },
{ NULL, NULL }
};
--- /dev/null
+++ b/lplumb.h
@@ -1,0 +1,14 @@
+#ifndef LPLUMB_H__
+#define LPLUMB_H__
+
+void registerplumbmsgmeta(lua_State *L);
+void pushplumbmsg(lua_State *L, Plumbmsg *m);
+Plumbmsg* checkplumbmsg(lua_State *L, int index);
+
+void registerplumbattrmeta(lua_State *L);
+void pushplumbattr(lua_State *L, Plumbattr *a);
+Plumbattr* checkplumbattr(lua_State *L, int index);
+
+int openlibplumb(lua_State *L);
+
+#endif
--- a/lua9.c
+++ b/lua9.c
@@ -5,10 +5,12 @@
#include <draw.h>
#include <event.h>
#include <keyboard.h>
+#include <plumb.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "ldraw.h"
+#include "lplumb.h"
#include "utils.h"
static const luaL_Reg libs[] = {
@@ -17,6 +19,7 @@
{ "g", openlibgeometry },
{ "key", openlibkey },
{ "color", openlibcolor },
+ { "plumb", openlibplumb },
{ NULL, NULL },
};
--- a/mkfile
+++ b/mkfile
@@ -14,6 +14,9 @@
event.$O \
key.$O \
color.$O \
+ plumb.$O \
+ plumbmsg.$O \
+ plumbattr.$O \
utils.$O \
lua9.$O
--- /dev/null
+++ b/plumb.c
@@ -1,0 +1,98 @@
+#include <u.h>
+#include <lib9.h>
+#include <plumb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include "lplumb.h"
+#include "utils.h"
+
+static int
+lopen(lua_State *L)
+{
+ char *port;
+ int omode, fd;
+ char err[128];
+
+ port = luaL_checkstring(L, 1);
+ omode = luaL_checkinteger(L, 2);
+ fd = plumbopen(port, omode);
+ if(fd < 0){
+ errstr(err, sizeof err);
+ lua_pushfstring(L, "unable to open plumb port '%s': %s", port, err);
+ return lua_error(L);
+ }
+ lua_pushinteger(L, fd);
+ return 1;
+}
+
+static int
+lclose(lua_State *L)
+{
+ int fd;
+
+ fd = luaL_checkinteger(L, 1);
+ //close(fd);
+ return 0;
+}
+
+static int
+lsendtext(lua_State *L)
+{
+ char *src, *dst, *wdir, *data;
+ int fd, n;
+
+ fd = luaL_checkinteger(L, 1);
+ src = luaL_optstring(L, 2, NULL);
+ dst = luaL_checkstring(L, 3);
+ wdir = luaL_optstring(L, 4, NULL);
+ data = luaL_checkstring(L, 5);
+ n = plumbsendtext(fd, src, dst, wdir, data);
+ lua_pushinteger(L, n);
+ return 1;
+}
+
+static int
+lrecv(lua_State *L)
+{
+ int fd;
+ Plumbmsg *m;
+
+ fd = luaL_checkinteger(L, 1);
+ m = plumbrecv(fd);
+ pushplumbmsg(L, m);
+ return 1;
+}
+
+static int
+lmsg(lua_State *L)
+{
+ void *p;
+
+ if(lua_islightuserdata(L, 1)){
+ p = lua_touserdata(L, 1);
+ pushplumbmsg(L, (Plumbmsg*)p);
+ } else
+ lua_pushnil(L);
+ return 1;
+}
+
+static const struct luaL_Reg libplumb [] = {
+ { "open", lopen },
+ { "close", lclose },
+ { "sendtext", lsendtext },
+ { "recv", lrecv },
+ { "msg", lmsg },
+ { NULL, NULL }
+};
+
+int
+openlibplumb(lua_State *L)
+{
+ registerplumbmsgmeta(L);
+ registerplumbattrmeta(L);
+ luaL_newlib(L, libplumb);
+ return 1;
+}
--- /dev/null
+++ b/plumbattr.c
@@ -1,0 +1,88 @@
+#include <plumb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include "lplumb.h"
+#include "utils.h"
+
+#define PLUMBATTR "Plumbattr"
+
+typedef struct LPlumbattr LPlumbattr;
+
+struct LPlumbattr
+{
+ Plumbattr *a;
+};
+
+void
+pushplumbattr(lua_State *L, Plumbattr *a)
+{
+ LPlumbattr *l;
+
+ l = (LPlumbattr*)lua_newuserdata(L, sizeof(LPlumbattr));
+ luaL_getmetatable(L, PLUMBATTR);
+ lua_setmetatable(L, -2);
+ l->a = a;
+}
+
+Plumbattr*
+checkplumbattr(lua_State *L, int index)
+{
+ LPlumbattr *l;
+
+ l = (LPlumbattr*)luaL_checkudata(L, index, PLUMBATTR);
+ luaL_argcheck(L, l != NULL, index, "Plumbattr expected");
+ return l->a;
+}
+
+static int
+plumbattr__gc(lua_State *L)
+{
+ /* already freed by plumbmsg gc */
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+static int
+plumbattr__tostring(lua_State *L)
+{
+ void *p;
+
+ p = lua_touserdata(L, 1);
+ lua_pushfstring(L, "plumbattr: %p", p);
+ return 1;
+}
+
+static int
+plumbattr__index(lua_State *L)
+{
+ Plumbattr *a;
+ const char *s;
+
+ a = checkplumbattr(L, 1);
+ s = luaL_checkstring(L, 2);
+ if(strncmp(s, "name", 4) == 0)
+ lua_pushstring(L, a->name);
+ else if(strncmp(s, "value", 5) == 0)
+ lua_pushstring(L, a->value);
+ else if(strncmp(s, "next", 4) == 0)
+ pushplumbattr(L, a->next);
+ else
+ return 0;
+ return 1;
+}
+
+static const struct luaL_Reg plumbattr_funcs[] = {
+ { "__gc", plumbattr__gc },
+ { "__tostring", plumbattr__tostring },
+ { "__index", plumbattr__index },
+ { NULL, NULL },
+};
+
+void
+registerplumbattrmeta(lua_State *L)
+{
+ createmetatable(L, PLUMBATTR, plumbattr_funcs);
+}
--- /dev/null
+++ b/plumbmsg.c
@@ -1,0 +1,99 @@
+#include <plumb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include "lplumb.h"
+#include "utils.h"
+
+#define PLUMBMSG "Plumbmsg"
+
+typedef struct LPlumbmsg LPlumbmsg;
+
+struct LPlumbmsg
+{
+ Plumbmsg *m;
+};
+
+void
+pushplumbmsg(lua_State *L, Plumbmsg *m)
+{
+ LPlumbmsg *l;
+
+ l = (LPlumbmsg*)lua_newuserdata(L, sizeof(LPlumbmsg));
+ luaL_getmetatable(L, PLUMBMSG);
+ lua_setmetatable(L, -2);
+ l->m = m;
+}
+
+Plumbmsg*
+checkplumbmsg(lua_State *L, int index)
+{
+ LPlumbmsg *l;
+
+ l = (LPlumbmsg*)luaL_checkudata(L, index, PLUMBMSG);
+ luaL_argcheck(L, l != NULL, index, "Plumbmsg expected");
+ return l->m;
+}
+
+static int
+plumbmsg__gc(lua_State *L)
+{
+ LPlumbmsg *l;
+
+ l = (LPlumbmsg*)luaL_checkudata(L, 1, PLUMBMSG);
+ luaL_argcheck(L, l != NULL, 1, "Plumbmsg expected");
+ plumbfree(l->m);
+ free(l);
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+static int
+plumbmsg__tostring(lua_State *L)
+{
+ void *p;
+
+ p = lua_touserdata(L, 1);
+ lua_pushfstring(L, "plumbmsg: %p", p);
+ return 1;
+}
+
+static int
+plumbmsg__index(lua_State *L)
+{
+ Plumbmsg *m;
+ const char *s;
+
+ m = checkplumbmsg(L, 1);
+ s = luaL_checkstring(L, 2);
+ if(strncmp(s, "src", 3) == 0)
+ lua_pushstring(L, m->src);
+ else if(strncmp(s, "dst", 3) == 0)
+ lua_pushstring(L, m->dst);
+ else if(strncmp(s, "wdir", 4) == 0)
+ lua_pushstring(L, m->wdir);
+ else if(strncmp(s, "type", 4) == 0)
+ lua_pushstring(L, m->type);
+ else if(strncmp(s, "data", 4) == 0)
+ lua_pushstring(L, m->data);
+ else if(strncmp(s, "attr", 4) == 0)
+ pushplumbattr(L, m->attr);
+ else
+ return 0;
+ return 1;
+}
+
+static const struct luaL_Reg plumbmsg_funcs[] = {
+ { "__gc", plumbmsg__gc },
+ { "__tostring", plumbmsg__tostring },
+ { "__index", plumbmsg__index },
+ { NULL, NULL },
+};
+
+void
+registerplumbmsgmeta(lua_State *L)
+{
+ createmetatable(L, PLUMBMSG, plumbmsg_funcs);
+}