cinvoke-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cinvoke-svn] r34 - in trunk/cinvoke: . bindings bindings/lua lib test


From: will
Subject: [cinvoke-svn] r34 - in trunk/cinvoke: . bindings bindings/lua lib test
Date: 18 Jun 2006 22:25:29 -0400

Author: will
Date: 2006-06-18 22:25:28 -0400 (Sun, 18 Jun 2006)
New Revision: 34

Added:
   trunk/cinvoke/bindings/
   trunk/cinvoke/bindings/lua/
   trunk/cinvoke/bindings/lua/Makefile
   trunk/cinvoke/bindings/lua/cinvoke_lua.c
   trunk/cinvoke/bindings/lua/test.lua
Modified:
   trunk/cinvoke/Makefile
   trunk/cinvoke/lib/Makefile
   trunk/cinvoke/lib/cinvoke.h
   trunk/cinvoke/test/Makefile
Log:
adding some code that will (hopefully) eventually become a lua binding,
updated build and docs


Modified: trunk/cinvoke/Makefile
===================================================================
--- trunk/cinvoke/Makefile      2006-06-16 13:38:05 UTC (rev 33)
+++ trunk/cinvoke/Makefile      2006-06-19 02:25:28 UTC (rev 34)
@@ -1,4 +1,4 @@
-PREFIX = /usr
+PREFIX = /usr/local
 
 all:
        cd lib && $(MAKE)
@@ -7,7 +7,7 @@
 install: all
        install lib/cinvoke.h lib/cinvoke-arch.h $(PREFIX)/include
        install lib/arch/gcc_x86_unix.h $(PREFIX)/include/cinvoke-archspec.h
-       install lib/cinvoke.a $(PREFIX)/lib
+       install lib/libcinvoke.a $(PREFIX)/lib
 
 clean:
        cd lib && $(MAKE) clean

Added: trunk/cinvoke/bindings/lua/Makefile
===================================================================
--- trunk/cinvoke/bindings/lua/Makefile                         (rev 0)
+++ trunk/cinvoke/bindings/lua/Makefile 2006-06-19 02:25:28 UTC (rev 34)
@@ -0,0 +1,20 @@
+TARGET = cinvoke_lua.so
+
+all: $(TARGET)
+
+test:
+       lua test.lua
+
+clean:
+       rm -f *.o $(TARGET)
+
+SRCS = cinvoke_lua.c
+
+OBJS = $(SRCS:.c=.o)
+
+$(TARGET): $(OBJS)
+       gcc -shared -o $(TARGET) $(OBJS) -llua -lcinvoke
+
+.c.o:
+       gcc -g -Wall -Werror -c $< -o $@
+

Added: trunk/cinvoke/bindings/lua/cinvoke_lua.c
===================================================================
--- trunk/cinvoke/bindings/lua/cinvoke_lua.c                            (rev 0)
+++ trunk/cinvoke/bindings/lua/cinvoke_lua.c    2006-06-19 02:25:28 UTC (rev 34)
@@ -0,0 +1,519 @@
+#include <lua.h>
+#include <cinvoke.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+void declbasic(lua_State *l, const char *g, cinv_type_t id, char charid) {
+       lua_newtable(l);
+       lua_pushstring(l, "basic");
+       lua_setfield(l, -2, "family");
+       lua_pushinteger(l, (lua_Integer)id);
+       lua_setfield(l, -2, "id");
+       lua_pushinteger(l, (lua_Integer)charid);
+       lua_setfield(l, -2, "charid");
+       lua_setglobal(l, g);
+}
+
+void declfunc(lua_State *l, const char *name, lua_CFunction func) {
+       lua_pushcfunction(l, func);
+       lua_setfield(l, -2, name);
+}
+
+int _cinv_chararray_to_string(lua_State *l) {
+       size_t len, i = 0;
+       char *ret;
+       if (lua_gettop(l) != 0) {
+               lua_pushstring(l, "usage: cinv.chararray_to_string(carray)");
+               lua_error(l);
+       }
+       len = lua_objlen(l, 1);
+
+       if (len == 0)
+               ret = "";
+       else {
+               ret = malloc(len + 1);
+               if (!ret) {
+                       lua_pushstring(l, "out of memory");
+                       lua_error(l);
+               }
+               lua_pushnil(l);
+               while (lua_next(l, 1) != 0) {
+                       if (i >= len)  break;
+
+                       ret[i] = (char)lua_tointeger(l, -1);
+
+                       lua_pop(l, 1);
+                       i++;
+               }
+
+               ret[len] = '\0';
+       }
+       
+       lua_pushlstring(l, ret, len);
+       return 1;
+}
+int _cinv_out(lua_State *l) {
+       if (lua_gettop(l) != 1) {
+               lua_pushstring(l, "usage: cinv.out(ptype)");
+               lua_error(l);
+       }
+       
+       lua_getfield(l, 1, "family");
+       if (!strcmp(lua_tostring(l, -1), "void")) {
+               lua_pushstring(l, "void is not a type");
+               lua_error(l);
+       }
+       lua_pop(l, 1);
+       
+       lua_newtable(l);
+       lua_pushnil(l);
+       while (lua_next(l, 1) != 0) {
+               lua_settable(l, -3);
+       }
+
+       lua_pushstring(l, "yes");
+       lua_setfield(l, -2, "out");
+
+       return 1;
+}
+int _cinv_array(lua_State *l) {
+       if (lua_gettop(l) != 1) {
+               lua_pushstring(l, "usage: cinv.array(arrtype)");
+               lua_error(l);
+       }
+       
+       lua_getfield(l, 1, "family");
+       if (!strcmp(lua_tostring(l, -1), "void")) {
+               lua_pushstring(l, "void is not a type");
+               lua_error(l);
+       }
+       lua_pop(l, 1);
+       
+       lua_newtable(l);
+       lua_pushnil(l);
+       while (lua_next(l, 1) != 0) {
+               lua_settable(l, -3);
+       }
+
+       lua_pushstring(l, "yes");
+       lua_setfield(l, -2, "array");
+
+       return 1;
+}
+
+struct LibStruct {
+       CInvContext *ctx;
+       CInvLibrary *lib;
+};
+
+int _clibrary_new(lua_State *l) {
+       CInvContext *ctx;
+       CInvLibrary *lib;
+       struct LibStruct *st;
+
+       if (lua_gettop(l) != 1) {
+               lua_pushstring(l, "usage: clibrary.new(libname)");
+               lua_error(l);
+       }
+
+       ctx = cinv_context_create();
+       if (ctx == NULL) {
+               lua_pushstring(l, "out of memory");
+               lua_error(l);
+       }
+       
+       lib = cinv_library_create(ctx, lua_tostring(l, 1));
+       if (lib == NULL) {
+               lua_pushstring(l, cinv_context_get_errormsg(ctx));
+               cinv_context_delete(ctx);
+               lua_error(l);
+       }
+       
+       st = lua_newuserdata(l, sizeof(struct LibStruct)); // return value
+       st->ctx = ctx;
+       st->lib = lib;
+       
+       lua_newtable(l);
+       lua_getglobal(l, "clibrary");
+       lua_setfield(l, -2, "__index");
+       lua_getglobal(l, "clibrary");
+       lua_getfield(l, -1, "dispose");
+       lua_setfield(l, -3, "__gc");
+       lua_pop(l, 1);
+       lua_setmetatable(l, -2);
+       return 1;
+}
+int _clibrary_dispose(lua_State *l) {
+       struct LibStruct *st;
+
+       if (lua_gettop(l) != 1) {
+               lua_pushstring(l, "usage: clibrary:dispose()");
+               lua_error(l);
+       }
+
+       st = lua_touserdata(l, 1);
+       if (st->lib) {
+               cinv_library_delete(st->ctx, st->lib);
+               st->lib = NULL;
+       }
+       if (st->ctx) {
+               cinv_context_delete(st->ctx);
+               st->ctx = NULL;
+       }
+       return 0;
+}
+
+// dont need explicit dispose methods for structures, callbacks or functions
+struct StrStruct {
+       CInvContext *ctx;
+       CInvStructure *st;
+};
+int _cstructure_gc(lua_State *l) {
+       struct StrStruct *st = lua_touserdata(l, 1);
+       if (st->st) {
+               cinv_structure_delete(st->ctx, st->st);
+               st->st = NULL;
+       }
+       if (st->ctx) {
+               cinv_context_delete(st->ctx);
+               st->ctx = NULL;
+       }
+       return 0;
+}
+
+int _cstructure_new(lua_State *l) {
+       struct StrStruct *ptr;
+       CInvContext *ctx;
+       CInvStructure *st;
+       int numargs, i;
+
+       ctx = cinv_context_create();
+       if (ctx == NULL) {
+               lua_pushstring(l, "out of memory");
+               lua_error(l);
+       }
+       
+       st = cinv_structure_create(ctx);
+       if (!st) {
+               lua_pushstring(l, cinv_context_get_errormsg(ctx));
+               cinv_context_delete(ctx);
+               lua_error(l);
+       }
+
+       numargs = lua_gettop(l);
+       if ((numargs % 2) != 0) {
+               lua_pushstring(l,
+                       "usage: cstructure.new(type, name, [type, name], ...");
+               goto error;
+       }
+
+       for (i = 1; i <= numargs; i += 2) {
+               const char *family;
+
+               lua_getfield(l, i, "out");
+               if (!lua_isnil(l, -1)) {
+                       lua_pushstring(l, "out modifier not valid for struct 
members");
+                       goto error;
+               }
+               lua_pop(l, 1);
+
+               lua_getfield(l, i, "family");
+               family = lua_tostring(l, -1);
+               if (!strcmp(family, "void")) {
+                       lua_pushstring(l, "void is not a type");
+                       goto error;
+               } else if (!strcmp(family, "string")) {
+                       if (!cinv_structure_addmember_value(ctx, st,
+                               lua_tostring(l, i + 1), CINV_T_PTR)) {
+                               lua_pushstring(l, 
cinv_context_get_errormsg(ctx));
+                               goto error;
+                       }
+               } else if (!strcmp(family, "struct")) {
+                       struct StrStruct *mem;
+                       lua_getfield(l, i, "ud");
+                       mem = lua_touserdata(l, -1);
+                       if (!cinv_structure_addmember_struct(ctx, st,
+                               lua_tostring(l, i + 1), mem->st)) {
+                               lua_pushstring(l, 
cinv_context_get_errormsg(ctx));
+                               goto error;
+                       }
+                       lua_pop(l, 1);
+               } else if (!strcmp(family, "basic")) {
+                       lua_Integer id;
+                       lua_getfield(l, i, "id");
+                       id = lua_tointeger(l, -1);
+                       if (!cinv_structure_addmember_value(ctx, st,
+                               lua_tostring(l, i + 1), (cinv_type_t)id)) {
+                               lua_pushstring(l, 
cinv_context_get_errormsg(ctx));
+                               goto error;
+                       }
+                       lua_pop(l, 1);
+               } else {
+                       lua_pushstring(l, "unknown family");
+                       goto error;
+               }
+               lua_pop(l, 1);
+       } 
+
+       if (!cinv_structure_finish(ctx, st)) {
+               lua_pushstring(l, cinv_context_get_errormsg(ctx));
+               goto error;
+       }
+
+       lua_newtable(l);
+       lua_pushstring(l, "struct");
+       lua_setfield(l, -2, "family");
+
+       lua_newtable(l);
+       for (i = 1; i <= numargs; i += 2) {
+               lua_pushvalue(l, i + 1);
+               lua_pushvalue(l, i);
+               lua_settable(l, -3);
+       }
+       lua_setfield(l, -2, "members");
+
+       ptr = lua_newuserdata(l, sizeof(struct StrStruct));
+       ptr->ctx = ctx;
+       ptr->st = st;
+       lua_newtable(l);
+       lua_pushcfunction(l, _cstructure_gc);
+       lua_setfield(l, -2, "__gc");
+       lua_setmetatable(l, -2);
+
+       lua_setfield(l, -2, "ud");
+       
+       return 1;
+
+error:
+       cinv_structure_delete(ctx, st);
+       cinv_context_delete(ctx);
+       lua_error(l);
+       return 0;
+}
+
+char getcode(lua_State *l, const char *family, int tblindex) {
+       lua_getfield(l, tblindex, "out");
+       if (!lua_isnil(l, -1)) {
+               lua_pop(l, 1);
+               return 'p';
+       }
+       lua_pop(l, 1);
+
+       lua_getfield(l, tblindex, "array");
+       if (!lua_isnil(l, -1)) {
+               lua_pop(l, 1);
+               return 'p';
+       }
+       lua_pop(l, 1);
+
+       if (!strcmp(family, "struct")) {
+               lua_pushstring(l,
+                       "passing or returning a struct by value is not yet 
supported");
+               return (char)-1;
+       } else if (!strcmp(family, "string")) {
+               return 'p';
+       } else if (!strcmp(family, "basic")) {
+               lua_getfield(l, tblindex, "charid");
+               lua_Integer charid = lua_tointeger(l, -1);
+               lua_pop(l, 1);
+               return (char)charid;
+       } else {
+               lua_pushstring(l, "unknown family");
+               return (char)-1;
+       }
+}
+
+CInvFunction *parsefunction(lua_State *l, CInvContext *ctx, int startarg) {
+       CInvFunction *ret;
+       char retfmt[2];
+       char *parmfmt;
+       int i;
+       int numparms = lua_gettop(l) - startarg - 1;
+       const char *family;
+
+       lua_getfield(l, startarg, "out");
+       if (!lua_isnil(l, -1)) {
+               lua_pushstring(l, "out modifier not valid for return type");
+               lua_error(l);
+       }
+       lua_pop(l, 1);
+       lua_getfield(l, startarg, "family");
+       family = lua_tostring(l, -1);
+       if (!strcmp("void", family))
+               retfmt[0] = '\0';
+       else {
+               retfmt[0] = getcode(l, family, startarg);
+               if (retfmt[0] == (char)-1)
+                       lua_error(l);
+               retfmt[1] = '\0';
+       }
+       lua_pop(l, 1);
+
+       parmfmt = malloc(numparms + 1);
+       if (!parmfmt) {
+               lua_pushstring(l, "out of memory");
+               lua_error(l);
+       }
+       for (i = startarg + 2; i <= numparms; i++) {
+               lua_getfield(l, i, "family");
+               family = lua_tostring(l, -1);
+               if (!strcmp("void", family)) {
+                       // only put up with void if it is the first and only 
parameter
+                       if (i == numparms && i == (startarg + 2)) {
+                               parmfmt[0] = '\0';
+                       } else {
+                               free(parmfmt);
+                               lua_pushstring(l, "void is an invalid parameter 
type");
+                               lua_error(l);
+                       }
+               } else {
+                       parmfmt[i - (startarg + 2)] = getcode(l, family, i);
+                       if (parmfmt[i - (startarg + 2)] == (char)-1) {
+                               free(parmfmt);
+                               lua_error(l);
+                       }
+               }
+       }
+       parmfmt[i - (startarg + 2)] = '\0';
+
+       ret = cinv_function_create(ctx, CINV_CC_DEFAULT, retfmt, parmfmt);
+       if (!ret) {
+               free(parmfmt);
+               lua_pushstring(l, cinv_context_get_errormsg(ctx));
+               lua_error(l);
+       }
+
+       free(parmfmt);
+       return ret;
+}
+
+int _ccallback_new(lua_State *l) {
+       // XXX
+       return 0;
+}
+
+struct FunStruct {
+       void *ep;
+       CInvFunction *func;
+       CInvContext *ctx;
+};
+
+int _function_gc(lua_State *l) {
+       struct FunStruct *fs = lua_touserdata(l, 1);
+       if (fs->func) {
+               cinv_function_delete(fs->ctx, fs->func);
+               fs->func = NULL;
+       }
+       return 0;
+}
+
+int _function_call(lua_State *l) {
+       // XXX
+       return 0;
+}
+
+int _clibrary_get_function(lua_State *l) {
+       struct FunStruct *fs;
+       struct LibStruct *lib;
+       CInvFunction *func;
+       void *ep;
+       int i;
+       int numargs = lua_gettop(l);
+       if (numargs < 3) {
+               lua_pushstring(l, "usage: clibrary:get_function(rettype, name, 
...)");
+               lua_error(l);
+       }
+
+       lib = lua_touserdata(l, 1);
+
+       func = parsefunction(l, lib->ctx, 2);
+
+       ep = cinv_library_load_entrypoint(lib->ctx, lib->lib, lua_tostring(l, 
3));
+       if (!ep) {
+               lua_pushstring(l, cinv_context_get_errormsg(lib->ctx));
+               cinv_function_delete(lib->ctx, func);
+               lua_error(l);
+       }
+       
+       lua_newtable(l);
+
+       lua_newtable(l);
+       lua_pushcfunction(l, _function_call);
+       lua_setfield(l, -2, "__call");
+       lua_setmetatable(l, -2);
+
+       fs = lua_newuserdata(l, sizeof(struct FunStruct));
+       fs->ep = ep;
+       fs->func = func;
+       fs->ctx = lib->ctx;
+       lua_newtable(l);
+       lua_pushcfunction(l, _function_gc);
+       lua_setfield(l, -2, "__gc");
+       lua_setmetatable(l, -2);
+       lua_setfield(l, -2, "ud");
+
+       lua_pushvalue(l, 2);
+       lua_setfield(l, -2, "return");
+       
+       lua_newtable(l);
+       for (i = 4; i <= numargs; i++) {
+               lua_pushinteger(l, i - 3);
+               lua_pushvalue(l, i);
+               lua_settable(l, -3);
+       }
+       lua_setfield(l, -2, "params");
+
+       // maintain a reference to parent library
+       lua_pushvalue(l, 1);
+       lua_setfield(l, -2, "lib");
+
+       return 1;
+}
+
+int luaopen_cinvoke_lua(lua_State *l) {
+       declbasic(l, "Cchar", CINV_T_CHAR, 'c');
+       declbasic(l, "Cshort", CINV_T_SHORT, 's');
+       declbasic(l, "Cint", CINV_T_INT, 'i');
+       declbasic(l, "Clong", CINV_T_LONG, 'l');
+       declbasic(l, "Clonglong", CINV_T_EXTRALONG, 'e');
+       declbasic(l, "Cfloat", CINV_T_FLOAT, 'f');
+       declbasic(l, "Cdouble", CINV_T_DOUBLE, 'd');
+       declbasic(l, "Cptr", CINV_T_PTR, 'p');
+       declbasic(l, "Cint16", CINV_T_2BYTE, '2');
+       declbasic(l, "Cint32", CINV_T_4BYTE, '4');
+       declbasic(l, "Cint64", CINV_T_8BYTE, '8');
+
+       lua_newtable(l);
+       lua_pushstring(l, "string");
+       lua_setfield(l, -2, "family");
+       lua_setglobal(l, "Cstring");
+
+       lua_newtable(l);
+       lua_pushstring(l, "void");
+       lua_setfield(l, -2, "family");
+       lua_setglobal(l, "Cvoid");
+
+       lua_newtable(l);
+       declfunc(l, "out", _cinv_out);
+       declfunc(l, "array", _cinv_array);
+       declfunc(l, "chararray_to_string", _cinv_chararray_to_string);
+       lua_setglobal(l, "cinv");
+
+       lua_newtable(l);
+       declfunc(l, "new", _clibrary_new);
+       declfunc(l, "get_function", _clibrary_get_function);
+       declfunc(l, "dispose", _clibrary_dispose);
+       lua_setglobal(l, "clibrary");
+
+       lua_newtable(l);
+       declfunc(l, "new", _ccallback_new);
+       lua_setglobal(l, "ccallback");
+       
+       lua_newtable(l);
+       declfunc(l, "new", _cstructure_new);
+       lua_setglobal(l, "cstructure");
+       
+       return 0;
+}
+

Added: trunk/cinvoke/bindings/lua/test.lua
===================================================================
--- trunk/cinvoke/bindings/lua/test.lua                         (rev 0)
+++ trunk/cinvoke/bindings/lua/test.lua 2006-06-19 02:25:28 UTC (rev 34)
@@ -0,0 +1,9 @@
+require("cinvoke_lua")
+
+libc = clibrary.new("libc.so.6")
+
+getpass = libc:get_function(Cstring, "getpass", CString)
+
+pass = getpass("Enter a password: ")
+
+print("You entered " .. pass)

Modified: trunk/cinvoke/lib/Makefile
===================================================================
--- trunk/cinvoke/lib/Makefile  2006-06-16 13:38:05 UTC (rev 33)
+++ trunk/cinvoke/lib/Makefile  2006-06-19 02:25:28 UTC (rev 34)
@@ -1,4 +1,4 @@
-TARGET = cinvoke.a
+TARGET = libcinvoke.a
 
 all: $(TARGET)
 
@@ -17,3 +17,11 @@
 .c.o:
        gcc -g -Wall -Werror -DARCH_GCC_X86_UNIX -DCINVOKE_BUILD -c $< -o $@
 
+cinvoke.o: cinvoke.c cinvoke.h cinvoke-arch.h arch/gcc_x86_unix.h \
+  cinvoke-private.h hashtable.h
+structure.o: structure.c cinvoke.h cinvoke-arch.h arch/gcc_x86_unix.h \
+  cinvoke-private.h hashtable.h
+hashtable.o: hashtable.c hashtable.h
+arch/gcc_x86_unix.o: arch/gcc_x86_unix.c arch/../cinvoke.h \
+  arch/../cinvoke-arch.h arch/../arch/gcc_x86_unix.h \
+  arch/../cinvoke-private.h arch/../hashtable.h

Modified: trunk/cinvoke/lib/cinvoke.h
===================================================================
--- trunk/cinvoke/lib/cinvoke.h 2006-06-16 13:38:05 UTC (rev 33)
+++ trunk/cinvoke/lib/cinvoke.h 2006-06-19 02:25:28 UTC (rev 34)
@@ -235,9 +235,11 @@
 * \li \b 2 - the integer type which uses 2 bytes on the current platform.
 * \li \b 4 - the integer type which uses 4 bytes on the current platform.
 * \li \b 8 - the integer type which uses 8 bytes on the current platform.
+*
 * Note that functions accepting or returning structures are not supported,
-* only pointers to structures. For example, a function with the following
-* prototype:
+* only pointers to structures.
+* \par Example
+* A function with the following prototype:
 * \code
 * int myfunction(char *ptr, float f);
 * \endcode

Modified: trunk/cinvoke/test/Makefile
===================================================================
--- trunk/cinvoke/test/Makefile 2006-06-16 13:38:05 UTC (rev 33)
+++ trunk/cinvoke/test/Makefile 2006-06-19 02:25:28 UTC (rev 34)
@@ -7,4 +7,4 @@
        gcc -g -shared -fPIC lib.c -o lib.so -Wall -Werror
 
 runtests: runtests.c lib.so
-       gcc -g -DCINVOKE_BUILD -DARCH_GCC_X86_UNIX -o runtests runtests.c -Wall 
-Werror ../lib/cinvoke.a -I../lib `sh ../tools/libdl.sh` -lm
+       gcc -g -DCINVOKE_BUILD -DARCH_GCC_X86_UNIX -o runtests runtests.c -Wall 
-Werror -L../lib -I../lib `sh ../tools/libdl.sh` -lcinvoke -lm





reply via email to

[Prev in Thread] Current Thread [Next in Thread]