Adding support for Python via swig

This commit is contained in:
Julien Palard 2011-10-22 16:45:31 +02:00
parent 6b4466c996
commit 1273370e93
7 changed files with 149 additions and 15 deletions

View File

@ -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

60
hl_vt100.i Normal file
View File

@ -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();
}
};

View File

@ -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 <<EOF | python
import hl_vt100
import time
import sys
print "Starting python test..."
vt100 = hl_vt100.vt100_headless()
vt100.fork('/usr/bin/top', ['/usr/bin/top', '-n', '1'])
vt100.main_loop()
[sys.stdout.write(line + "\n") for line in vt100.getlines()]
EOF
exit
fi
if [ "$1" = c ]
then
make && make test
/lib/ld-linux.so.2 --library-path . ./test /usr/bin/top
exit
fi
$0 python
$0 c

23
setup.py Normal file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env python
"""
setup.py file for hl_vt100
"""
from distutils.core import setup, Extension
hl_vt100_module = Extension('_hl_vt100',
sources=['hl_vt100_wrap.c',
'src/hl_vt100.c',
'src/lw_terminal_parser.c',
'src/lw_terminal_vt100.c'],
)
setup (name = 'hl_vt100',
version = '0.1',
author = "Julien Palard",
description = """Headless vt100 emulator""",
ext_modules = [hl_vt100_module],
py_modules = ["hl_vt100"],
)

View File

@ -1,16 +1,19 @@
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <utmp.h>
#include <string.h>
#include <pty.h>
#include <stdlib.h>
#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);
}

View File

@ -3,6 +3,10 @@
#define CHILD 0
#include <utmp.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
#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

View File

@ -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;
}