From 1273370e9383d215c32a4bf4a72f199f5bdc73c3 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Sat, 22 Oct 2011 16:45:31 +0200 Subject: [PATCH] Adding support for Python via swig --- Makefile | 10 ++++++++- hl_vt100.i | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ run_tests.sh | 33 ++++++++++++++++++++++++++- setup.py | 23 +++++++++++++++++++ src/hl_vt100.c | 22 ++++++++++-------- src/hl_vt100.h | 10 +++++++-- src/test.c | 6 +++-- 7 files changed, 149 insertions(+), 15 deletions(-) create mode 100644 hl_vt100.i create mode 100644 setup.py diff --git a/Makefile b/Makefile index 4e99539..c7f3d22 100644 --- a/Makefile +++ b/Makefile @@ -31,13 +31,21 @@ $(NAME): $(OBJ) test: $(OBJ_TEST) $(CC) $(OBJ_TEST) -L . -l$(NAME) -o test +python_module: + swig -python *.i + python setup.py build_ext --inplace + all: @make $(NAME) .c.o: $(CC) -D $(DEFINE) -c $(CFLAGS) $< -o $(<:.c=.o) -clean: +clean_python_module: + $(RM) *.pyc *.so hl_vt100_wrap.c hl_vt100.py + $(RM) -r build + +clean: clean_python_module $(RM) $(LINKERNAME) test src/*~ *~ src/\#*\# src/*.o \#*\# *.o *core re: clean all diff --git a/hl_vt100.i b/hl_vt100.i new file mode 100644 index 0000000..f6f1492 --- /dev/null +++ b/hl_vt100.i @@ -0,0 +1,60 @@ +%module hl_vt100 + +%{ +#include "src/lw_terminal_vt100.h" +#include "src/hl_vt100.h" +%} + +%typemap(in) char ** { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $1 = (char **) malloc((size+1)*sizeof(char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyString_Check(o)) + $1[i] = PyString_AsString(PyList_GetItem($input,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free($1); + return NULL; + } + } + $1[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } + } + +%typemap(out) char ** { + /* Check if is a list */ + int i; + + $result = PyList_New(0); + for (i = 0; i < arg1->term->height; i++) + PyList_Append($result, PyString_FromStringAndSize($1[i], arg1->term->width)); + } + + +// This cleans up the char ** array we malloc'd before the function call +%typemap(freearg) char ** { + free((char *) $1); + } + +struct vt100_headless +{ + void (*changed)(struct vt100_headless *this); +%immutable; + int master; + struct termios backup; + struct lw_terminal_vt100 *term; + %extend { + vt100_headless(); + ~vt100_headless(); + void fork(const char *progname, char **argv); + char **getlines(); + int main_loop(); + } +}; diff --git a/run_tests.sh b/run_tests.sh index 998bb6c..2d764dd 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,2 +1,33 @@ #!/bin/sh -make && make test && /lib/ld-linux.so.2 --library-path . ./test vttest +if [ "$1" = python ] +then + make python_module + if [ $? != 0 ] + then + echo "Failed to build python module" + exit 1 + fi + cat < #include -#include -#include #include #include #include #include "hl_vt100.h" -struct vt100_headless *vt100_headless_init(void) +struct vt100_headless *new_vt100_headless(void) { - return malloc(sizeof(struct vt100_headless)); + return calloc(1, sizeof(struct vt100_headless)); +} + +void delete_vt100_headless(struct vt100_headless *this) +{ + free(this); } static void set_non_canonical(struct vt100_headless *this, int fd) @@ -59,7 +62,7 @@ static void strdump(char *str) } #endif -static int main_loop(struct vt100_headless *this) +int vt100_headless_main_loop(struct vt100_headless *this) { char buffer[4096]; fd_set rfds; @@ -100,9 +103,11 @@ static int main_loop(struct vt100_headless *this) strdump(buffer); #endif lw_terminal_vt100_read_str(this->term, buffer); - this->changed(this); + if (this->changed != NULL) + this->changed(this); } } + return EXIT_SUCCESS; } void master_write(void *user_data, void *buffer, size_t len) @@ -120,14 +125,14 @@ const char **vt100_headless_getlines(struct vt100_headless *this) void vt100_headless_fork(struct vt100_headless *this, const char *progname, - char *const argv[]) + char **argv) { int child; struct winsize winsize; set_non_canonical(this, 0); winsize.ws_row = 24; - winsize.ws_col = 24; + winsize.ws_col = 80; child = forkpty(&this->master, NULL, NULL, NULL); if (child == CHILD) { @@ -141,7 +146,6 @@ void vt100_headless_fork(struct vt100_headless *this, this->term = lw_terminal_vt100_init(this, lw_terminal_parser_default_unimplemented); this->term->master_write = master_write; ioctl(this->master, TIOCSWINSZ, &winsize); - main_loop(this); } restore_termios(this, 0); } diff --git a/src/hl_vt100.h b/src/hl_vt100.h index 7f7a581..ecc783a 100644 --- a/src/hl_vt100.h +++ b/src/hl_vt100.h @@ -3,6 +3,10 @@ #define CHILD 0 +#include +#include +#include +#include #include "lw_terminal_vt100.h" struct vt100_headless @@ -14,8 +18,10 @@ struct vt100_headless }; -void vt100_headless_fork(struct vt100_headless *this, const char *progname, char *const argv[]); -struct vt100_headless *vt100_headless_init(void); +void vt100_headless_fork(struct vt100_headless *this, const char *progname, char **argv); +int vt100_headless_main_loop(struct vt100_headless *this); +void delete_vt100_headless(struct vt100_headless *this); +struct vt100_headless *new_vt100_headless(void); const char **vt100_headless_getlines(struct vt100_headless *this); #endif diff --git a/src/test.c b/src/test.c index f7572b2..1d26bb4 100644 --- a/src/test.c +++ b/src/test.c @@ -15,8 +15,9 @@ void disp(struct vt100_headless *vt100) write(1, "\n", 1); for (y = 0; y < vt100->term->height; ++y) { + write(1, "|", 1); write(1, lines[y], vt100->term->width); - write(1, "\n", 1); + write(1, "|\n", 2); } } @@ -29,8 +30,9 @@ int main(int ac, char **av) puts("Usage: test PROGNAME"); return EXIT_FAILURE; } - vt100_headless = vt100_headless_init(); + vt100_headless = new_vt100_headless(); vt100_headless->changed = disp; vt100_headless_fork(vt100_headless, av[1], (av + 1)); + vt100_headless_main_loop(vt100_headless); return EXIT_SUCCESS; }