Initial revision. Adding CFFI module.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@8059 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
a92239d201
commit
7cfedfae05
2 changed files with 654 additions and 0 deletions
96
SWIG/Lib/cffi/cffi.swg
Normal file
96
SWIG/Lib/cffi/cffi.swg
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* Define a C preprocessor symbol that can be used in interface files
|
||||
to distinguish between the SWIG language modules. */
|
||||
|
||||
#define SWIG_CFFI
|
||||
|
||||
/* Typespecs for basic types. */
|
||||
|
||||
%typemap(cin) void ":void";
|
||||
|
||||
%typemap(cin) char ":char";
|
||||
%typemap(cin) char * ":string";
|
||||
%typemap(cin) unsigned char ":unsigned-char";
|
||||
%typemap(cin) signed char ":char";
|
||||
|
||||
%typemap(cin) short ":short";
|
||||
%typemap(cin) signed short ":short";
|
||||
%typemap(cin) unsigned short ":unsigned-short";
|
||||
|
||||
%typemap(cin) int ":int";
|
||||
%typemap(cin) signed int ":int";
|
||||
%typemap(cin) unsigned int ":unsigned-nt";
|
||||
|
||||
%typemap(cin) long ":long";
|
||||
%typemap(cin) signed long ":long";
|
||||
%typemap(cin) unsigned long ":unsigned-long";
|
||||
|
||||
%typemap(cin) float ":float";
|
||||
%typemap(cin) double ":double";
|
||||
%typemap(cin) SWIGTYPE ":pointer";
|
||||
|
||||
%typemap(cout) void ":void";
|
||||
|
||||
%typemap(cout) char ":char";
|
||||
%typemap(cout) char * ":string";
|
||||
%typemap(cout) unsigned char ":unsigned-char";
|
||||
%typemap(cout) signed char ":char";
|
||||
|
||||
%typemap(cout) short ":short";
|
||||
%typemap(cout) signed short ":short";
|
||||
%typemap(cout) unsigned short ":unsigned-short";
|
||||
|
||||
%typemap(cout) int ":int";
|
||||
%typemap(cout) signed int ":int";
|
||||
%typemap(cout) unsigned int ":unsigned-nt";
|
||||
|
||||
%typemap(cout) long ":long";
|
||||
%typemap(cout) signed long ":long";
|
||||
%typemap(cout) unsigned long ":unsigned-long";
|
||||
|
||||
%typemap(cout) float ":float";
|
||||
%typemap(cout) double ":double";
|
||||
%typemap(cout) SWIGTYPE ":pointer";
|
||||
|
||||
|
||||
%typemap(ctype) bool "int";
|
||||
%typemap(ctype) char, unsigned char, signed char,
|
||||
short, signed short, unsigned short,
|
||||
int, signed int, unsigned int,
|
||||
long, signed long, unsigned long,
|
||||
float, double, long double, char *, void *, void,
|
||||
enum SWIGTYPE, SWIGTYPE *,
|
||||
SWIGTYPE[ANY], SWIGTYPE & "$1_ltype";
|
||||
%typemap(ctype) SWIGTYPE "$&1_type";
|
||||
|
||||
%typemap(in) bool "$1 = (bool)$input;";
|
||||
%typemap(in) char, unsigned char, signed char,
|
||||
short, signed short, unsigned short,
|
||||
int, signed int, unsigned int,
|
||||
long, signed long, unsigned long,
|
||||
float, double, long double, char *, void *, void,
|
||||
enum SWIGTYPE, SWIGTYPE *,
|
||||
SWIGTYPE[ANY], SWIGTYPE & "$1 = $input;";
|
||||
%typemap(in) SWIGTYPE "$1 = *$input;";
|
||||
|
||||
%typemap(out) bool "$result = (int)$1;";
|
||||
%typemap(out) char, unsigned char, signed char,
|
||||
short, signed short, unsigned short,
|
||||
int, signed int, unsigned int,
|
||||
long, signed long, unsigned long,
|
||||
float, double, long double, char *, void *, void,
|
||||
enum SWIGTYPE, SWIGTYPE *,
|
||||
SWIGTYPE[ANY], SWIGTYPE & "$result = $1;";
|
||||
%typemap(out) SWIGTYPE "$result = new $1_type($1);";
|
||||
|
||||
|
||||
%{
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN extern "C"
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
#define EXPORT EXTERN SWIGEXPORT
|
||||
|
||||
%}
|
||||
558
SWIG/Source/Modules/cffi.cxx
Normal file
558
SWIG/Source/Modules/cffi.cxx
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* cffi.cxx
|
||||
*
|
||||
* cffi module.
|
||||
*
|
||||
* Author(s) : Surendra Singhi (surendra@asu.edu)
|
||||
*
|
||||
* Copyright (C) 2005 Surendra Singhi
|
||||
* See the file LICENSE for information on usage and redistribution.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
char cvsroot_cffi_cxx[] = "$Header$";
|
||||
|
||||
#include <ctype.h>
|
||||
#include "swigmod.h"
|
||||
#include "cparse.h"
|
||||
|
||||
#define CFFI_DEBUG
|
||||
class CFFI : public Language {
|
||||
public:
|
||||
File *f_cl;
|
||||
String *f_clhead;
|
||||
String *f_clwrap;
|
||||
|
||||
File *f_cxx;
|
||||
File *f_cxx_header;
|
||||
File *f_cxx_wrapper;
|
||||
|
||||
String *module;
|
||||
virtual void main(int argc, char *argv[]);
|
||||
virtual int top(Node *n);
|
||||
virtual int functionWrapper(Node *n);
|
||||
virtual int variableWrapper(Node *n);
|
||||
virtual int constantWrapper(Node *n);
|
||||
// virtual int classDeclaration(Node *n);
|
||||
virtual int enumDeclaration(Node *n);
|
||||
virtual int typedefHandler(Node *n);
|
||||
|
||||
//c++ specific code
|
||||
virtual int constructorHandler(Node *n);
|
||||
virtual int destructorHandler(Node *n);
|
||||
virtual int memberfunctionHandler(Node *n);
|
||||
virtual int membervariableHandler(Node *n);
|
||||
virtual int classHandler(Node *n);
|
||||
|
||||
private:
|
||||
void emit_defun(Node *n, String *name);
|
||||
void emit_struct_union(Node *n, bool un);
|
||||
String* lispify_name(String *ty);
|
||||
String* convert_literal(String *num_param, String *type);
|
||||
String* strip_parens(String *string);
|
||||
int extern_all_flag;
|
||||
int generate_typedef_flag;
|
||||
};
|
||||
|
||||
void CFFI :: main(int argc, char *argv[]) {
|
||||
int i;
|
||||
|
||||
SWIG_library_directory("cffi");
|
||||
SWIG_config_file("cffi.swg");
|
||||
generate_typedef_flag = 0;
|
||||
extern_all_flag=0;
|
||||
|
||||
for(i=1; i<argc; i++) {
|
||||
if (!Strcmp(argv[i], "-help")) {
|
||||
Printf(stdout, "cffi Options (available with -cffi)\n");
|
||||
Printf(stdout,
|
||||
" -extern-all\n"
|
||||
"\t If this option is given then cffi definitions for all the functions\n"
|
||||
"and global variables will be created otherwise only definitions for \n"
|
||||
"externed functions and variables are created.\n"
|
||||
" -generate-typedef\n"
|
||||
"\t If this option is given then defctype will be used to generate shortcuts\n"
|
||||
"according to the typedefs in the input.\n"
|
||||
" -lispify-identifiers\n"
|
||||
"\t If this option is given then while converting C identified to symbols they"
|
||||
"will be lispified.\n"
|
||||
);
|
||||
}
|
||||
else if ( (Strcmp(argv[i],"-extern-all") == 0)) {
|
||||
extern_all_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
}
|
||||
else if ( (Strcmp(argv[i],"-generate-typedef") == 0)) {
|
||||
generate_typedef_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
}
|
||||
}
|
||||
f_clhead = NewString("");
|
||||
f_clwrap = NewString("");
|
||||
}
|
||||
|
||||
int CFFI :: top(Node *n) {
|
||||
module=Getattr(n, "name");
|
||||
|
||||
String *cxx_filename=Getattr(n, "outfile");
|
||||
String *lisp_filename=NewString("");
|
||||
|
||||
Printf(lisp_filename, "%s%s.lisp", SWIG_output_directory(), module);
|
||||
f_cl=NewFile(lisp_filename, "w");
|
||||
if (!f_cl) {
|
||||
FileErrorDisplay(lisp_filename);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (CPlusPlus)
|
||||
{
|
||||
f_cxx=NewFile(cxx_filename, "w");
|
||||
if (!f_cxx) {
|
||||
Close(f_cl); Delete(f_cl);
|
||||
Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
f_cxx=NewString("");
|
||||
|
||||
f_cxx_header = f_cxx;
|
||||
f_cxx_wrapper=NewString("");
|
||||
|
||||
Swig_register_filebyname("header",f_cxx_header);
|
||||
Swig_register_filebyname("wrapper",f_cxx_wrapper);
|
||||
Swig_register_filebyname("runtime",f_cxx);
|
||||
Swig_register_filebyname("lisp", f_clwrap);
|
||||
Swig_register_filebyname("lisphead", f_cl);
|
||||
|
||||
Language::top(n);
|
||||
|
||||
Printf(f_cl, "%s\n", f_clhead);
|
||||
Printf(f_cl, "%s\n", f_clwrap);
|
||||
|
||||
Printf(stderr, "All done now!\n");
|
||||
Close(f_cl);
|
||||
Delete(f_cl); // Deletes the handle, not the file
|
||||
Delete(f_clhead);
|
||||
Delete(f_clwrap);
|
||||
Close(f_cxx);
|
||||
Delete(f_cxx);
|
||||
Delete(f_cxx_wrapper);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
int CFFI :: classHandler(Node *n) {
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr, "class %s::%s\n", "some namespace",//current_namespace,
|
||||
Getattr(n, "sym:name"));
|
||||
#endif
|
||||
String *name=Getattr(n, "sym:name");
|
||||
String *kind = Getattr(n,"kind");
|
||||
|
||||
// maybe just remove this check and get rid of the else clause below.
|
||||
if (Strcmp(kind, "struct") == 0 )
|
||||
{
|
||||
emit_struct_union(n,false);
|
||||
return SWIG_OK;
|
||||
}
|
||||
else if (Strcmp(kind, "union") == 0 )
|
||||
{
|
||||
emit_struct_union(n,true);
|
||||
return SWIG_OK;
|
||||
}
|
||||
else if (Strcmp(kind, "class") == 0)
|
||||
{
|
||||
Language::classHandler(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf(stderr, "Don't know how to deal with %s kind of class yet.\n",
|
||||
kind);
|
||||
Printf(stderr, " (name: %s)\n", name);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
int CFFI :: constructorHandler(Node *n)
|
||||
{
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr, "constructor %s\n", Getattr(n, "name"));
|
||||
Printf(stderr, "constructor %s\n and %s and %s",Getattr(n,"kind"),Getattr(n,"sym:name"),Getattr(n,"allegrocl:old-sym:name"));
|
||||
#endif
|
||||
|
||||
// Let SWIG generate a global forwarding function.
|
||||
return Language::constructorHandler(n);
|
||||
}
|
||||
|
||||
int CFFI :: destructorHandler(Node *n)
|
||||
{
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr, "destructor %s\n", Getattr(n, "name"));
|
||||
#endif
|
||||
|
||||
// Let SWIG generate a global forwarding function.
|
||||
return Language::destructorHandler(n);
|
||||
}
|
||||
|
||||
int CFFI :: memberfunctionHandler(Node *n) {
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr, "member function %s::%s\n",
|
||||
Getattr(parentNode(n), "name"), Getattr(n, "name"));
|
||||
#endif
|
||||
|
||||
// Let SWIG generate a global forwarding function.
|
||||
return Language::memberfunctionHandler(n);
|
||||
}
|
||||
|
||||
int CFFI :: membervariableHandler(Node *n) {
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr, "member variable %s::%s\n",
|
||||
Getattr(parentNode(n), "name"), Getattr(n, "name"));
|
||||
#endif
|
||||
|
||||
// Let SWIG generate a get/set function pair.
|
||||
return Language::membervariableHandler(n);
|
||||
}
|
||||
|
||||
int CFFI :: functionWrapper(Node *n) {
|
||||
|
||||
ParmList *parms = Getattr(n,"parms");
|
||||
String *iname = Getattr(n,"sym:name");
|
||||
Wrapper *wrap = NewWrapper();
|
||||
char wname[256];
|
||||
|
||||
String *raw_return_type = Swig_typemap_lookup_new("ctype",n,"",0);
|
||||
SwigType *return_type = Swig_cparse_type(raw_return_type);
|
||||
SwigType *resolved = SwigType_typedef_resolve_all(return_type);
|
||||
int is_void_return = (Cmp(resolved, "void") == 0);
|
||||
Delete(resolved);
|
||||
|
||||
if (!is_void_return)
|
||||
{
|
||||
String *lresult_init = NewStringf("lresult = (%s)0", raw_return_type);
|
||||
Wrapper_add_localv(wrap,"lresult", raw_return_type, lresult_init, NIL);
|
||||
Delete(lresult_init);
|
||||
}
|
||||
|
||||
String *overname = 0;
|
||||
if (Getattr(n,"sym:overloaded")) {
|
||||
overname = Getattr(n,"sym:overname");
|
||||
} else {
|
||||
if (!addSymbol(iname,n))
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
|
||||
String *nw = Swig_name_wrapper(iname);
|
||||
strcpy(wname,Char(nw));
|
||||
Delete(nw);
|
||||
if (overname) {
|
||||
strcat(wname,Char(overname));
|
||||
}
|
||||
|
||||
// Emit all of the local variables for holding arguments.
|
||||
emit_args(Getattr(n, "type"), parms, wrap);
|
||||
|
||||
// Attach the standard typemaps
|
||||
Swig_typemap_attach_parms("ctype", parms, wrap);
|
||||
emit_attach_parmmaps(parms, wrap);
|
||||
|
||||
int num_arguments = emit_num_arguments(parms);
|
||||
String *name_and_parms = NewStringf("%s (", wname);
|
||||
int i; Parm *p;
|
||||
int gencomma = 0;
|
||||
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr, "function %s - %d\n", Getattr(n, "name"),num_arguments);
|
||||
#endif
|
||||
|
||||
for (i = 0, p=parms; i < num_arguments; i++) {
|
||||
|
||||
while (checkAttribute(p,"tmap:in:numinputs","0")) {
|
||||
p = Getattr(p,"tmap:in:next");
|
||||
}
|
||||
|
||||
SwigType *c_parm_type = Swig_cparse_type(Getattr(p, "tmap:ctype"));
|
||||
String *arg = NewStringf("l%s", Getattr(p,"lname"));
|
||||
|
||||
// Emit parameter declaration
|
||||
if (gencomma) Printf(name_and_parms, ", ");
|
||||
String *parm_decl = SwigType_str(c_parm_type, arg);
|
||||
Printf(name_and_parms, "%s", parm_decl);
|
||||
#ifdef CFFI_DEBUG
|
||||
Printf(stderr," param: %s\n", parm_decl);
|
||||
#endif
|
||||
Delete(parm_decl);
|
||||
gencomma = 1;
|
||||
|
||||
// Emit parameter conversion code
|
||||
String *parm_code = Getattr(p,"tmap:in");
|
||||
{
|
||||
Replaceall(parm_code,"$input", arg);
|
||||
Setattr(p,"emit:input", arg);
|
||||
Printf(wrap->code,"%s\n", parm_code);
|
||||
p = Getattr(p,"tmap:in:next");
|
||||
}
|
||||
|
||||
Delete(arg);
|
||||
}
|
||||
Printf(name_and_parms, ")");
|
||||
|
||||
// Emit the function definition
|
||||
String *signature = SwigType_str(return_type, name_and_parms);
|
||||
Printf(wrap->def, "EXPORT %s {", signature);
|
||||
Printf(wrap->code," try {\n");
|
||||
emit_action(n, wrap);
|
||||
if (!is_void_return)
|
||||
{
|
||||
String *result_convert = Swig_typemap_lookup_new("out",n,"result",0);
|
||||
Replaceall(result_convert, "$result", "lresult");
|
||||
Printf(wrap->code, "%s\n", result_convert);
|
||||
Printf(wrap->code, " return lresult;\n");
|
||||
Delete(result_convert);
|
||||
}
|
||||
|
||||
Printf(wrap->code," } catch (...) {\n");
|
||||
if (!is_void_return)
|
||||
Printf(wrap->code," return (%s)0;\n", raw_return_type);
|
||||
Printf(wrap->code," }\n");
|
||||
Printf(wrap->code,"}\n");
|
||||
|
||||
if (CPlusPlus)
|
||||
Wrapper_print(wrap, f_cxx);
|
||||
|
||||
if (CPlusPlus)
|
||||
emit_defun(n,wname);
|
||||
else
|
||||
emit_defun(n,iname);
|
||||
|
||||
// if (!overloaded || !Getattr(n, "sym:nextSibling")) {
|
||||
// update_package_if_needed(n);
|
||||
// emit_buffered_defuns(n);
|
||||
// // this is the last overload.
|
||||
// if (overloaded) {
|
||||
// emit_dispatch_defun(n);
|
||||
// }
|
||||
// }
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
||||
void CFFI::emit_defun(Node *n,String *name)
|
||||
{
|
||||
|
||||
// String *storage=Getattr(n,"storage");
|
||||
// if(!extern_all_flag && (!storage || (Strcmp(storage,"extern") && Strcmp(storage,"externc"))))
|
||||
// return SWIG_OK;
|
||||
|
||||
String *func_name=Getattr(n, "sym:name");
|
||||
|
||||
ParmList *pl=Getattr(n, "parms");
|
||||
|
||||
int argnum=0, first=1;
|
||||
|
||||
Printf(f_cl, "\n(defcfun (\"%s\" %s)", name, func_name);
|
||||
String *ffitype= Swig_typemap_lookup_new("cout",n,":pointer",0);
|
||||
|
||||
Printf(f_cl, " %s", ffitype);
|
||||
Delete(ffitype);
|
||||
|
||||
for (Parm *p=pl; p; p=nextSibling(p), argnum++) {
|
||||
|
||||
String *argname=Getattr(p, "name");
|
||||
|
||||
ffitype = Swig_typemap_lookup_new("cin",p, "",0);
|
||||
|
||||
int tempargname=0;
|
||||
|
||||
if (!argname) {
|
||||
argname=NewStringf("arg%d", argnum);
|
||||
tempargname=1;
|
||||
}
|
||||
|
||||
Printf(f_cl, "\n (%s %s)", argname, ffitype);
|
||||
first=0;
|
||||
|
||||
Delete(ffitype);
|
||||
|
||||
if (tempargname)
|
||||
Delete(argname);
|
||||
}
|
||||
Printf(f_cl, ")\n"); /* finish arg list */
|
||||
}
|
||||
|
||||
|
||||
int CFFI :: constantWrapper(Node *n) {
|
||||
String *type=Getattr(n, "type");
|
||||
String *converted_value=convert_literal(Getattr(n, "value"), type);
|
||||
String *name=Getattr(n, "sym:name");
|
||||
|
||||
Printf(f_cl, "\n(defconstant %s %s)\n", name, converted_value);
|
||||
Delete(converted_value);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
int CFFI :: variableWrapper(Node *n) {
|
||||
String *storage=Getattr(n,"storage");
|
||||
|
||||
if(!extern_all_flag && (!storage || (Strcmp(storage,"extern") && Strcmp(storage,"externc"))))
|
||||
return SWIG_OK;
|
||||
|
||||
String *var_name=Getattr(n, "sym:name");
|
||||
String *lisp_type = Swig_typemap_lookup_new("cin",n, "",0);
|
||||
Printf(f_cl,"\n(defcvar (\"%s\" %s)\n %s)\n",var_name,var_name,lisp_type);
|
||||
|
||||
Delete(lisp_type);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
int CFFI :: typedefHandler(Node *n) {
|
||||
if(generate_typedef_flag) {
|
||||
Printf(f_cl,"\n(defctype %s %s)\n",Getattr(n,"name"),Swig_typemap_lookup_new("cin",n, "",0));
|
||||
}
|
||||
return Language::typedefHandler(n);
|
||||
}
|
||||
|
||||
int CFFI :: enumDeclaration(Node *n) {
|
||||
String *name=Getattr(n, "sym:name");
|
||||
|
||||
Printf(f_cl,"\n(defcenum %s ",name);
|
||||
|
||||
for (Node *c=firstChild(n); c; c=nextSibling(c)) {
|
||||
|
||||
String *slot_name = Getattr(c, "name");
|
||||
String *value = Getattr(c, "enumvalue");
|
||||
|
||||
Printf(f_cl,"(:%s %s)",slot_name,value);
|
||||
|
||||
Delete(value);
|
||||
}
|
||||
|
||||
Printf(f_cl, ")\n");
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
// Includes structs
|
||||
void CFFI :: emit_struct_union(Node *n, bool un=false) {
|
||||
String *name=Getattr(n, "sym:name");
|
||||
String *kind = Getattr(n,"kind");
|
||||
|
||||
if (Strcmp(kind, "struct")) {
|
||||
Printf(stderr, "Don't know how to deal with %s kind of class yet.\n",
|
||||
kind);
|
||||
Printf(stderr, " (name: %s)\n", name);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(un)
|
||||
Printf(f_cl,"\n(defcunion %s",name);
|
||||
else
|
||||
Printf(f_cl,"\n(defcstruct %s",name);
|
||||
|
||||
for (Node *c=firstChild(n); c; c=nextSibling(c)) {
|
||||
|
||||
if (Strcmp(nodeType(c), "cdecl")) {
|
||||
Printf(stderr, "Structure %s has a slot that we can't deal with.\n",
|
||||
name);
|
||||
Printf(stderr, "nodeType: %s, name: %s, type: %s\n",
|
||||
nodeType(c),
|
||||
Getattr(c, "name"),
|
||||
Getattr(c, "type"));
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
String *temp=Copy(Getattr(c,"decl"));
|
||||
Append(temp,Getattr(c,"type")); //appending type to the end, otherwise wrong type
|
||||
String *lisp_type=Swig_typemap_lookup_new("cin",c, "",0);
|
||||
Delete(temp);
|
||||
|
||||
String *slot_name = Getattr(c, "sym:name");
|
||||
Printf(f_cl,
|
||||
"\n\t(%s %s)",
|
||||
slot_name,
|
||||
lisp_type);
|
||||
|
||||
Delete(lisp_type);
|
||||
}
|
||||
|
||||
Printf(f_cl, ")\n");
|
||||
|
||||
/* Add this structure to the known lisp types */
|
||||
//Printf(stdout, "Adding %s foreign type\n", name);
|
||||
// add_defined_foreign_type(name);
|
||||
|
||||
}
|
||||
|
||||
/* utilities */
|
||||
/* returns new string w/ parens stripped */
|
||||
String* CFFI::strip_parens(String *string) {
|
||||
char *s=Char(string), *p;
|
||||
int len=Len(string);
|
||||
String *res;
|
||||
|
||||
if (len==0 || s[0] != '(' || s[len-1] != ')') {
|
||||
return NewString(string);
|
||||
}
|
||||
|
||||
p=(char *)malloc(len-2+1);
|
||||
if (!p) {
|
||||
Printf(stderr, "Malloc failed\n");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
strncpy(p, s+1, len-1);
|
||||
p[len-2]=0; /* null terminate */
|
||||
|
||||
res=NewString(p);
|
||||
free(p);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
String* CFFI::convert_literal(String *num_param, String *type) {
|
||||
String *num=strip_parens(num_param), *res;
|
||||
char *s=Char(num);
|
||||
|
||||
/* Make sure doubles use 'd' instead of 'e' */
|
||||
if (!Strcmp(type, "double")) {
|
||||
String *updated=Copy(num);
|
||||
if (Replace(updated, "e", "d", DOH_REPLACE_ANY) > 1) {
|
||||
Printf(stderr, "Weird!! number %s looks invalid.\n", num);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
Delete(num);
|
||||
return updated;
|
||||
}
|
||||
|
||||
if (SwigType_type(type) == T_CHAR) {
|
||||
/* Use CL syntax for character literals */
|
||||
return NewStringf("#\\%s", num_param);
|
||||
}
|
||||
else if (SwigType_type(type) == T_STRING) {
|
||||
/* Use CL syntax for string literals */
|
||||
return NewStringf("\"%s\"", num_param);
|
||||
}
|
||||
|
||||
if (Len(num) < 2 || s[0] != '0') {
|
||||
return num;
|
||||
}
|
||||
|
||||
/* octal or hex */
|
||||
|
||||
res=NewStringf("#%c%s",
|
||||
s[1] == 'x' ? 'x' : 'o',
|
||||
s+2);
|
||||
Delete(num);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
extern "C" Language *swig_cffi(void) {
|
||||
return new CFFI();
|
||||
}
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue