Support for enums and typedefs.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10691 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
e90a0692c7
commit
9c5ef7558c
4 changed files with 190 additions and 42 deletions
|
|
@ -13,7 +13,10 @@ top_builddir = @top_builddir@/..
|
|||
C_TEST_CASES =
|
||||
|
||||
CPP_TEST_CASES = \
|
||||
c_arguments
|
||||
exception_order \
|
||||
exception_partial_info \
|
||||
enums \
|
||||
enum_plus \
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
|
|
|
|||
12
Lib/c/c.swg
12
Lib/c/c.swg
|
|
@ -39,6 +39,7 @@ typedef struct {
|
|||
%typemap(ctype) SWIGTYPE * "SwigObj *"
|
||||
%typemap(ctype) SWIGTYPE & "SwigObj *"
|
||||
%typemap(ctype) SWIGTYPE * [ANY] "SwigObj *"
|
||||
%typemap(ctype) enum SWIGTYPE "$1_type"
|
||||
|
||||
%fragment("stdbool_inc", "proxy_header") {#include <stdbool.h>}
|
||||
%typemap(ctype, fragment="stdbool_inc") bool, bool *, bool **, const bool, const bool *, bool * [ANY] "$1_type"
|
||||
|
|
@ -60,6 +61,8 @@ typedef struct {
|
|||
%typemap(in, fragment="stdbool_inc") bool, bool *, bool **, const bool, const bool *, bool * [ANY] "$1 = ($1_type) $input;"
|
||||
%typemap(in, fragment="stdbool_inc") bool &, const bool & "$1 = ($1_basetype *) $input;"
|
||||
|
||||
%typemap(in) enum SWIGTYPE "$1 = ($1_type) $input;"
|
||||
|
||||
%typemap(in) SWIGTYPE {
|
||||
$1 = * ($1_type *) ($input->obj);
|
||||
}
|
||||
|
|
@ -98,9 +101,10 @@ typedef struct {
|
|||
%typemap(couttype) const void *, const short *, const int *, const long *, const char *, const float *, const double * "$1_type"
|
||||
%typemap(couttype) short &, int &, long &, char &, float &, double &, bool & "$1_basetype *"
|
||||
%typemap(couttype) const short &, const int &, const long &, const char &, const float &, const double & "$1_basetype const *"
|
||||
%typemap(couttype) SWIGTYPE "SwigObj *"
|
||||
%typemap(couttype) SWIGTYPE * "SwigObj *"
|
||||
%typemap(couttype) SWIGTYPE & "SwigObj *"
|
||||
%typemap(couttype) SWIGTYPE "SwigObj *"
|
||||
%typemap(couttype) SWIGTYPE * "SwigObj *"
|
||||
%typemap(couttype) SWIGTYPE & "SwigObj *"
|
||||
%typemap(couttype) enum SWIGTYPE "$1_type"
|
||||
|
||||
%typemap(couttype, fragment="stdbool_inc") bool, bool *, const bool, const bool * "$1_type"
|
||||
%typemap(couttype, fragment="stdbool_inc") bool &, const bool & "$1_basetype *"
|
||||
|
|
@ -120,6 +124,8 @@ typedef struct {
|
|||
%typemap(out, fragment="stdbool_inc") bool, bool *, const bool, const bool * "$result = $1;"
|
||||
%typemap(out, fragment="stdbool_inc") bool &, const bool & "$result = $1;"
|
||||
|
||||
%typemap(out) enum SWIGTYPE "$result = ($1_type) $1;"
|
||||
|
||||
// allocate new "object-struct" by default
|
||||
|
||||
%typemap(out) SWIGTYPE {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
char cvsroot_c_cxx[] = "$Id$";
|
||||
|
||||
#include <ctype.h>
|
||||
#include "swigmod.h"
|
||||
|
||||
class C:public Language {
|
||||
|
|
@ -26,6 +27,8 @@ class C:public Language {
|
|||
String *f_proxy_header;
|
||||
|
||||
String *empty_string;
|
||||
String *int_string;
|
||||
String *enum_values;
|
||||
|
||||
bool proxy_flag;
|
||||
bool runtime_flag;
|
||||
|
|
@ -39,6 +42,8 @@ public:
|
|||
|
||||
C() :
|
||||
empty_string(NewString("")),
|
||||
int_string(NewString("int")),
|
||||
enum_values(0),
|
||||
proxy_flag(true),
|
||||
runtime_flag(true),
|
||||
typecheck_flag(false) {
|
||||
|
|
@ -187,7 +192,7 @@ public:
|
|||
SwigType *type = Getattr(n, "type");
|
||||
String *type_str = SwigType_str(type, 0);
|
||||
if (proxy_flag) {
|
||||
Printv(f_proxy_header, "SWIGIMPORT ", type_str, " ", Getattr(n, "name"), ";\n", NIL);
|
||||
Printv(f_proxy_header, "SWIGIMPORT ", type_str, " ", Getattr(n, "name"), ";\n\n", NIL);
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -270,6 +275,35 @@ public:
|
|||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* make_enum_type()
|
||||
*
|
||||
* given C++ enum type this function returns its C representation
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
String *make_enum_type(Node *n, SwigType *enumtype) {
|
||||
Symtab *symtab = Getattr(n, "sym:symtab");
|
||||
String *unnamed = Getattr(n, "unnamed");
|
||||
String *newtype = 0;
|
||||
String *query = 0;
|
||||
|
||||
if (!unnamed)
|
||||
query = Swig_scopename_last(SwigType_str(enumtype, 0));
|
||||
else {
|
||||
Replaceall(unnamed, "$unnamed", "enum");
|
||||
Replaceall(unnamed, "$", "");
|
||||
query = unnamed;
|
||||
}
|
||||
|
||||
Node *node = Swig_symbol_clookup(query, symtab);
|
||||
if (node)
|
||||
newtype = NewStringf("enum %s", Getattr(node, "name"));
|
||||
else
|
||||
newtype = Copy(enumtype);
|
||||
|
||||
return newtype;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* functionWrapper()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -286,7 +320,7 @@ public:
|
|||
String *proto = NewString("");
|
||||
String *over_suffix = NewString("");
|
||||
int gencomma;
|
||||
bool is_void_return = (SwigType_type(Getattr(n, "type")) == T_VOID);
|
||||
bool is_void_return = (SwigType_type(type) == T_VOID);
|
||||
|
||||
// create new function wrapper object
|
||||
Wrapper *wrapper = NewWrapper();
|
||||
|
|
@ -304,7 +338,7 @@ public:
|
|||
Delitem(arg_names, 0);
|
||||
Delitem(arg_names, DOH_END);
|
||||
}
|
||||
return_type = SwigType_str(Getattr(n, "type"), 0);
|
||||
return_type = SwigType_str(type, 0);
|
||||
|
||||
// emit wrapper prototype and code
|
||||
gencomma = 0;
|
||||
|
|
@ -341,16 +375,16 @@ public:
|
|||
wname = Swig_name_wrapper(name);
|
||||
Setattr(n, "wrap:name", wname);
|
||||
|
||||
// attach the standard typemaps
|
||||
emit_attach_parmmaps(parms, wrapper);
|
||||
Setattr(n, "wrap:parms", parms);
|
||||
|
||||
// set the return type
|
||||
if (Cmp(Getattr(n, "c:objstruct"), "1") == 0) {
|
||||
Printv(return_type, SwigType_str(type, 0), NIL);
|
||||
}
|
||||
else if (SwigType_isenum(type)) {
|
||||
type = return_type = make_enum_type(n, type);
|
||||
Setattr(n, "type", return_type);
|
||||
}
|
||||
else if ((tm = Swig_typemap_lookup("couttype", n, "", 0))) {
|
||||
String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
|
||||
String *ctypeout = Getattr(n, "tmap:couttype:out");
|
||||
if (ctypeout)
|
||||
tm = ctypeout;
|
||||
Printf(return_type, "%s", tm);
|
||||
|
|
@ -359,23 +393,27 @@ public:
|
|||
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No couttype typemap defined for %s\n", SwigType_str(type, 0));
|
||||
}
|
||||
|
||||
// attach 'ctype' typemaps
|
||||
Swig_typemap_attach_parms("ctype", parms, wrapper);
|
||||
|
||||
// emit variables for holding parameters
|
||||
emit_parameter_variables(parms, wrapper);
|
||||
|
||||
// add variable for holding result of original function
|
||||
if (!is_void_return && (Cmp(Getattr(n, "c:objstruct"), "1") != 0)) {
|
||||
if (SwigType_isconst(type))
|
||||
SwigType_del_qualifier(type);
|
||||
SwigType *return_var_type = SwigType_isreference(type) ? SwigType_add_pointer(SwigType_base(type)) : type;
|
||||
Wrapper_add_localv(wrapper, "cppresult", SwigType_str(return_var_type, 0), "cppresult", NIL);
|
||||
if (SwigType_isenum(type))
|
||||
Wrapper_add_localv(wrapper, "cppresult", "int", "cppresult", NIL);
|
||||
else
|
||||
Wrapper_add_localv(wrapper, "cppresult", SwigType_str(return_var_type, 0), "cppresult", NIL);
|
||||
}
|
||||
|
||||
// create wrapper function prototype
|
||||
Printv(wrapper->def, "SWIGEXPORTC ", return_type, " ", wname, "(", NIL);
|
||||
|
||||
// attach the standard typemaps
|
||||
emit_attach_parmmaps(parms, wrapper);
|
||||
Setattr(n, "wrap:parms", parms);
|
||||
|
||||
// attach 'ctype' typemaps
|
||||
Swig_typemap_attach_parms("ctype", parms, wrapper);
|
||||
|
||||
// prepare function definition
|
||||
gencomma = 0;
|
||||
for (p = parms; p; ) {
|
||||
|
|
@ -392,9 +430,20 @@ public:
|
|||
|
||||
Printf(arg_name, "c%s", lname);
|
||||
|
||||
bool dont_apply_tmap = false;
|
||||
|
||||
// set the appropriate type for parameter
|
||||
if (Cmp(Getattr(p, "c:objstruct"), "1") == 0) {
|
||||
Printv(c_parm_type, SwigType_str(type, 0), NIL);
|
||||
dont_apply_tmap = true;
|
||||
}
|
||||
else if (SwigType_isenum(type)) {
|
||||
c_parm_type = make_enum_type(n, type);
|
||||
if (Getattr(n, "unnamed")) {
|
||||
type = int_string;
|
||||
Setattr(p, "type", type);
|
||||
dont_apply_tmap = true;
|
||||
}
|
||||
}
|
||||
else if ((tm = Getattr(p, "tmap:ctype"))) {
|
||||
Printv(c_parm_type, tm, NIL);
|
||||
|
|
@ -412,8 +461,6 @@ public:
|
|||
Printv(proxy_parm_type, c_parm_type, NIL);
|
||||
}
|
||||
|
||||
Replaceall(c_parm_type, "::", "_");
|
||||
|
||||
Printv(arg_names, gencomma ? ", " : "", Getattr(p, "name"), NIL);
|
||||
Printv(wrapper->def, gencomma ? ", " : "", c_parm_type, " ", arg_name, NIL);
|
||||
Printv(proto, gencomma ? ", " : "", proxy_parm_type, " ", Getattr(p, "name"), NIL);
|
||||
|
|
@ -421,8 +468,7 @@ public:
|
|||
|
||||
// apply typemaps for input parameter
|
||||
if ((tm = Getattr(p, "tmap:in"))) {
|
||||
if (Cmp(Getattr(p, "c:objstruct"), "1") == 0) {
|
||||
// FIXME: should work as typemaps for basic types
|
||||
if (dont_apply_tmap) {
|
||||
Printv(wrapper->code, lname, " = ", arg_name, ";\n", NIL);
|
||||
}
|
||||
else {
|
||||
|
|
@ -443,6 +489,9 @@ public:
|
|||
|
||||
Printf(wrapper->def, ") {");
|
||||
|
||||
// emit variables for holding parameters
|
||||
emit_parameter_variables(parms, wrapper);
|
||||
|
||||
// emit variable for holding function return value
|
||||
emit_return_variable(n, return_type, wrapper);
|
||||
|
||||
|
|
@ -462,6 +511,8 @@ public:
|
|||
Replaceall(action, "$mod", ref_cast);
|
||||
Delete(ref_cast);
|
||||
}
|
||||
else if (SwigType_isenum(type))
|
||||
Replaceall(action, "$mod", "(int)");
|
||||
else
|
||||
Replaceall(action, "$mod", "");
|
||||
|
||||
|
|
@ -525,13 +576,13 @@ public:
|
|||
void emit_runtime_typecheck(String *classname, String *funcname, String *code) {
|
||||
Printf(code, "{\nint i = 0, type_ok = 0;\n");
|
||||
Printf(code, "if (arg1 == NULL) {\n");
|
||||
Printv(code, " fprintf(stderr, \"error: NULL object-struct passed to ", funcname, "\\n\");\n");
|
||||
Printv(code, " fprintf(stdout, \"error: NULL object-struct passed to ", funcname, "\\n\");\n");
|
||||
Printf(code, " longjmp(Swig_rt_env, 0);\n}\n");
|
||||
Printf(code, "while(arg1->typenames[i]) {\n");
|
||||
Printv(code, " if (strcmp(arg1->typenames[i++], \"", classname, "\") == 0) {\n", NIL);
|
||||
Printf(code, " type_ok = 1;\nbreak;\n}\n}\n");
|
||||
Printf(code, "if (!type_ok) {\n");
|
||||
Printv(code, " fprintf(stderr, \"error: object-struct passed to ", funcname, " is not of class ", classname, "\\n\");\n", NIL);
|
||||
Printv(code, " fprintf(stdout, \"error: object-struct passed to ", funcname, " is not of class ", classname, "\\n\");\n", NIL);
|
||||
Printf(code, " longjmp(Swig_rt_env, 0);\n}\n}\n");
|
||||
}
|
||||
|
||||
|
|
@ -614,20 +665,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// emit "class"-struct definition
|
||||
Printv(sobj, "struct SwigObj", name, " {\n void* obj;\n", NIL);
|
||||
if (runtime_flag)
|
||||
//Printf(sobj, " const char *typenames[%d];\n}", Len(baselist) + 2);
|
||||
Printf(sobj, " const char **typenames;\n}");
|
||||
else
|
||||
Printf(sobj, "}");
|
||||
|
||||
Printv(f_header, sobj, ";\n\n", NIL);
|
||||
Printv(f_header, "const char* Swig_typename_", name, " = \"", name, "\";\n\n", NIL);
|
||||
|
||||
// declare it in the proxy header
|
||||
// declare type for specific class in the proxy header
|
||||
if (proxy_flag)
|
||||
//Printv(f_proxy_header, "#define ", name, " SwigObj\n\n", NIL);
|
||||
Printv(f_proxy_header, "typedef SwigObj ", name, ";\n\n", NIL);
|
||||
|
||||
Delete(sobj);
|
||||
|
|
@ -809,7 +850,6 @@ public:
|
|||
}
|
||||
Append(action, code);
|
||||
Setattr(n, "wrap:action", action);
|
||||
Setattr(n, "type", "void");
|
||||
|
||||
functionWrapper(n);
|
||||
|
||||
|
|
@ -842,6 +882,8 @@ public:
|
|||
if (!SwigType_isconst(type)) {
|
||||
// create code for 'set' function
|
||||
code = NewString("");
|
||||
if (SwigType_isenum(Getattr(n, "type")) && Getattr(n, "unnamed"))
|
||||
Printf(code, "* (int *) &");
|
||||
Printv(code, classname, "::", name, " = arg1;\n", NIL);
|
||||
wrap_set_variable(n, classname, newclassname, name, code);
|
||||
}
|
||||
|
|
@ -890,8 +932,13 @@ public:
|
|||
// create 'set' function
|
||||
set_nextSibling(p, t);
|
||||
Setattr(n, "parms", p);
|
||||
String *code = 0;
|
||||
if (SwigType_isenum(Getattr(n, "type")) && Getattr(n, "unnamed")) {
|
||||
code = NewString("");
|
||||
Printv(code, "* (int *) &((", classname, "*) arg1->obj)->", name, " = arg2;\n", NIL);
|
||||
}
|
||||
Setattr(n, "type", "void");
|
||||
wrap_set_variable(n, classname, newclassname, name, 0);
|
||||
wrap_set_variable(n, classname, newclassname, name, code);
|
||||
}
|
||||
|
||||
Delete(new_name);
|
||||
|
|
@ -1080,9 +1127,59 @@ public:
|
|||
|
||||
/* ---------------------------------------------------------------------
|
||||
* enumDeclaration()
|
||||
*
|
||||
* for enums declared inside class we create global enum declaration
|
||||
* and change enum parameter and return value names
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
virtual int enumDeclaration(Node *n) {
|
||||
String *newclassname = Getattr(parentNode(n), "sym:name");
|
||||
String *name = Getattr(n, "sym:name");
|
||||
String *code = NewString("");
|
||||
String *tdname = Getattr(n, "tdname");
|
||||
String *newname = newclassname ? NewStringf("%s_", newclassname) : Copy(name);
|
||||
Symtab *symtab = Getattr(n, "sym:symtab");
|
||||
|
||||
if (tdname)
|
||||
Printf(code, "typedef ");
|
||||
|
||||
Printf(code, "enum ");
|
||||
|
||||
if (Delattr(n, "unnamed")) {
|
||||
// unnamed enum declaration: create new symbol
|
||||
Replaceall(name, "$unnamed", "enum");
|
||||
Delitem(name, DOH_END);
|
||||
|
||||
Node *entry = NewHash();
|
||||
set_nodeType(entry, "enum");
|
||||
Setattr(entry, "name", name);
|
||||
Setattr(entry, "sym:name", name);
|
||||
Setattr(entry, "sym:symtab", symtab);
|
||||
Swig_symbol_add(name, entry);
|
||||
}
|
||||
|
||||
if (newclassname) {
|
||||
if (symtab) {
|
||||
Node *node = Swig_symbol_clookup(name, symtab);
|
||||
if (node) {
|
||||
Append(newname, name);
|
||||
Setattr(node, "name", newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
Printv(code, newname ? newname : "", " {\n$enumvalues\n} ", tdname ? tdname : "", ";\n\n", NIL);
|
||||
emit_children(n);
|
||||
if (enum_values) {
|
||||
Replaceall(code, "$enumvalues", enum_values);
|
||||
Append(f_proxy_header, code);
|
||||
if (newclassname)
|
||||
Append(f_header, code);
|
||||
Delete(enum_values);
|
||||
enum_values = 0;
|
||||
}
|
||||
|
||||
Delete(newname);
|
||||
Delete(code);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1091,6 +1188,48 @@ public:
|
|||
* --------------------------------------------------------------------- */
|
||||
|
||||
virtual int enumvalueDeclaration(Node *n) {
|
||||
String *name = Getattr(n, "sym:name");
|
||||
String *enumvalue = Getattr(n, "enumvalue");
|
||||
String *init = 0;
|
||||
if (enumvalue) {
|
||||
char *value_repr = Char(enumvalue);
|
||||
if (value_repr)
|
||||
if (!isdigit(*value_repr) && *value_repr != '+') {
|
||||
init = NewStringf(" = '%c'", *value_repr);
|
||||
}
|
||||
else
|
||||
init = NewStringf(" = %s", enumvalue);
|
||||
}
|
||||
|
||||
String *newclassname = Getattr(parentNode(parentNode(n)), "sym:name");
|
||||
String *newname = NewStringf("%s_%s", newclassname, name);
|
||||
int gencomma = 1;
|
||||
if (!enum_values) {
|
||||
enum_values = NewString("");
|
||||
gencomma = 0;
|
||||
}
|
||||
Printv(enum_values, gencomma ? ",\n " : " ", newclassname ? newname : name, enumvalue ? init : "", NIL);
|
||||
Delete(newname);
|
||||
if (init)
|
||||
Delete(init);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* typedefHandler()
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
virtual int typedefHandler(Node *n) {
|
||||
String *name = Getattr(n, "sym:name");
|
||||
String *type = Getattr(n, "type");
|
||||
char *c = Char(SwigType_str(type, 0));
|
||||
if (strncmp(c, "enum", 4) != 0) {
|
||||
if (name && type) {
|
||||
String *code = NewStringf("typedef %s %s;\n\n", type, name);
|
||||
Append(f_proxy_header, code);
|
||||
Delete(code);
|
||||
}
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1959,10 +1959,10 @@ SKIP_UFFI=
|
|||
#fi
|
||||
AC_SUBST(SKIP_UFFI)
|
||||
|
||||
SKIP_C=""
|
||||
#if test -x "$(CC)" || test -z "$(CXX)" ; then
|
||||
# SKIP_C="1"
|
||||
#fi
|
||||
SKIP_C=
|
||||
if test -x "$CC" || test -z "$CXX" ; then
|
||||
SKIP_C="1"
|
||||
fi
|
||||
AC_SUBST(SKIP_C)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue