This is the mail archive of the guile@cygnus.com mailing list for the guile project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi again, Guile folks: Since some people are looking for a way to automatically generate Guile wrapper functions directly from function declarations, I have hacked together a very simple minded tool allowing G-Wrap to do this. It is not incredibly sophisticated, but I have converted my own libraries to use it and it has worked well for me. Simply putting the proper comment before the ANSI declaration in a source or header file triggers the generation of the wrapper function. e.g. Scanning the following text in a header file: /*[EXPORT] * Calculates eigenvectors Z and eigenvalues w of real symmetric matrix A, * using Lapack. */ void eig_dsyev(MAT *A, MAT *Z, VEC* w); is equivalent to putting (new-function 'eig-dsyev 'void "eig_dsyev" ((MAT A) (MAT Z) (VEC w)) "Calculates eigenvectors Z and eigenvalues w of real symmetric matrix A, using Lapack.") in your g-wrap declarations file. This is assuming you have prepared for using VEC and MAT with the lines such as the following in the g-wrap description file: (set! type-translations (append '((VEC* VEC) (MAT* MAT)) type-translations)) (new-type 'VEC "VEC" "VEC_print" "v_free" "VEC_eq") (new-type 'MAT "MAT" "MAT_print" "m_free" "MAT_eq") The README file follows. Feel free to criticize this first attempt (or to rewrite it yourself the "right" way and tell me about it so I can use it myself :) -Chris ============================== README =================================== G-Translate Copyright (C) 1997 Christopher Lee ********************************************************************** G-Translate is available from the g-wrap page: http://www.cs.cmu.edu/~chrislee/g-wrap ***** INSTALL ***** To install, edit the Makefile and type 'make install'. ***** INTRODUCTION ***** G-Translate is an experimental extension to G-Wrap, consisting of a program 'g-scan' and a Guile module (g-wrap g-translate) which scan source code for functions to export. Instead of manually writing g-wrap descriptions of functions you want to export, you can load the g-translate module in your description file with (use-modules (g-wrap g-translate)) and scan automatically for functions to export using this command: (gwrap-c-scan-source-file "g-scan.c") This command, gwrap-c-scan-source-file, looks through "g-scan.c" for ANSI function declarations that are preceded by comments starting with "\n/*[EXPORT" and does some simplistic parsing to find out enough about a function to write a wrapper function to export it to the Scheme interpreter. For example, since g-scan.c includes the following text: /*[EXPORT (name my-string-append)] * Returns the result of appending strings st1 and str2. */ char * string_append(char* str1, char *str2) { char *ret = get_string(strlen(str1)+strlen(str2)); strcpy(ret,str1); strcat(ret,str2); return ret; } a G-Wrap wrapper for the function would be created so that calling (my-string-append "g-" "wrap") in the interpreter should return the string "g-wrap". To export a function, simply add the following comment before an ANSI function declaration: /*[EXPORT <flags>] <Description> */ Where <description> is a short description of what the function does, and <flags> (usually left empty) can indicate that g-translate should override its default assumptions about return type, parameter types, or function name. If <flags> contains: (name <new-name>) -- the function is exported as <new-name> (types ((<n> <new-type>) ...)) -- the type of the <n>-th parameter (the first parameter is 0) is assumed to be <new-type> (ret-type <new-type>) -- the return type of the function is assumed to be <new-type> Up to three characters of each line of <description> are ignored if they are space or '*' characters. ***** NOTES ***** I have tested this on some large libraries I use for my work and it is very convenient. However, there are many open issues: 1) The inclusion of a (uses-modules ...) clause in the description file is wrong, and it should be done in the file 'g-wrap-guile' from g-wrap instead. 2) Parsing and error handling are extremely simplistic. 3) C-preprocessing is not supported, since the trigger text for exporting a function is in the comments. 4) K&R C is not supported 5) The <flags> are read as C-text and then written inside of parentheses to be parsed by Scheme. If unparsable text or unbalanced parentheses are part of the <flags> specification, then the Scheme read will fail. ***** G-SCAN ***** G-Translate uses a (brain-dead?) parser program written in C called g-scan to scan through sources and header files for functions to export. G-Scan reads through a file for comments starting with [newline] and then "/*[EXPORT". After seeing this, it stores all text until the next "]" character as a 'flags' string, then stores all text until the next "*/" as a description string. Next, it expects to see an ANSI C function declaration, which must look "normal" and have its return type specified. g-scan then outputs a Scheme list of the form (<scheme-fn-name> <flags> <arg-lst> <ret-type> <c-fn-name> <doc-string>) where <scheme-fn-name> is the name of the functions with all underscores '_' translated to dashes '-', and <arg-list> is a list of (<type> <param-name>) lists. Running "g-scan g-scan.c" results in: (string-append ((name my-string-append)) char* "string_append" ((char* str1) (char* str2) ) "Returns the result of appending strings st1 and str2. ")