[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cinvoke-svn] r34 - in trunk/cinvoke: . bindings bindings/lua lib test,
will <=