diff --git a/src/swig/Makefile b/src/swig/Makefile new file mode 100644 index 0000000000..c043904a80 --- /dev/null +++ b/src/swig/Makefile @@ -0,0 +1,70 @@ + +SWIG_FILTER := %P.h %/util.h +SWIG_HDRS := $(filter-out ${SWIG_FILTER},$(wildcard ../engine/*.h)) + +# Because Swig's include mechanism is not too smart. +SWIG_BASENAMES := $(notdir ${SWIG_HDRS}) + +CFLAGS := -I.. \ + -I../.. \ + -I../engine \ + -I../register \ + -I./../../include \ + -I/usr/include/readline \ + -I/usr/lib/perl5/i386-linux/5.004/CORE + +CFLAGS += -O2 -Wall -Wno-unused + +LIBENG := ../libengine.a + +all: guile perl5 + +# This is .PHONY because it has to be re-generated *every* time. Who +# knows when headers are added to the engine dir? +xacc.i: + @echo "%module xacc" > xacc.i + @echo "%{" >> xacc.i + @($(foreach hdr,${SWIG_BASENAMES},echo "#include <${hdr}>"; )) >> xacc.i + @echo "%}" >> xacc.i + @($(foreach hdr,${SWIG_BASENAMES},echo %include ${hdr}; )) >> xacc.i +.PHONY: xacc.i + +%_wrap.c: xacc.i + +##### Guile + +guile: guile/xacc-guile +.PHONY: guile + +##### Guile + +xacc-guile: xacc-guile.o xacc-guile_wrap.o $(LIBENG) + +guile/xacc-guile_wrap.c: xacc.i ${SWIG_HDRS} + swig -I../engine -guile -o $@ $< + +guile/xacc-guile: guile/xacc-guile.o guile/xacc-guile_wrap.o $(LIBENG) + ${CC} $^ ${LIBENG} -lguile -lreadline -lm -o $@ +CLEANFILES += guile/xacc-guile + +##### Perl5 + +perl5: perl5/xacc.so + +perl5/xacc.so: perl5/xacc-perl5_wrap.c $(LIBENG) + ${CC} ${CFLAGS} -shared $^ -lm -o $@ -Dbool=char -fpic +CLEANFILES += perl5/xacc.so + +perl5/xacc-perl5_wrap.c: xacc.i ${SWIG_HDRS} + swig -I../engine -perl5 -o $@ $< + +clean: + rm -f *.o *~ *.bak *.i ${CLEANFILES} + (cd guile && rm -f *.o *~ *.bak *_wrap.c *.doc) + (cd perl5 && rm -f *.o *~ *.bak *_wrap.c *.doc *.pm) + +# Local Variables: +# tab-width: 2 +# End: + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/src/swig/README b/src/swig/README new file mode 100644 index 0000000000..5408064a65 --- /dev/null +++ b/src/swig/README @@ -0,0 +1,18 @@ + +This README needs some serious help. + +./examples contains whatever examples we've accumulated to date. + +Each language interface is built in a separate subdirectory. Right +now we have guile and perl5. A simple "make" should build everything. + +Building guile will result in guile/xacc-guile, a simple interpreter +that will let you execute scheme forms (including xacc commands). We +need to add an example of building a dynamically loadable guile module +later, but guile/xacc-guile.c shows you how easy it is to embed a +guile interpreter in your app, and then load all the xacc functions +into the interpreter. + +Building perl5 will result in a perl module. For an example of how to +use it, see ../cbb/cbb-to-xacc. + diff --git a/src/swig/examples/scan-acct.scm b/src/swig/examples/scan-acct.scm new file mode 100644 index 0000000000..bfedf0a8e1 --- /dev/null +++ b/src/swig/examples/scan-acct.scm @@ -0,0 +1,8 @@ + +(define (list-accts filename) + (let ((db (xaccReadAccountGroup filename))) + (do ((total (xaccGetNumAccounts db)) + (i 0 (+ i 1))) + ((= i total)) + (let ((acct (xaccGetAccountFromID db i))) + (write (xaccAccountGetName acct)))))) diff --git a/src/swig/guile/xacc-guile.c b/src/swig/guile/xacc-guile.c new file mode 100644 index 0000000000..63933446a5 --- /dev/null +++ b/src/swig/guile/xacc-guile.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +static void +guile_entry_point(int argc, char *argv[]) { + char *input; + xacc(); + + input = readline("xacc> "); + while(input) { + SCM result = gh_eval_str(input); + gh_display(result); + gh_newline(); + add_history(input); + free(input); + input = readline("xacc> "); + } +} + +int +main(int argc, char *argv[]) { + gh_enter(argc, argv, guile_entry_point); + return 0; +}