Merge remote-tracking branch 'upstream/master' into OCaml-INPUT-OUTPUT-INOUT-primitives

This commit is contained in:
Zackery Spytz 2019-05-08 14:05:02 -06:00
commit 2f48bec666
363 changed files with 5825 additions and 2936 deletions

View file

@ -1552,6 +1552,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
Parm *throws;
String *throwf;
String *nexcept;
String *final;
} dtype;
struct {
const char *type;
@ -1567,6 +1568,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
ParmList *throws;
String *throwf;
String *nexcept;
String *final;
} decl;
Parm *tparms;
struct {
@ -1648,7 +1650,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
/* C declarations */
%type <node> c_declaration c_decl c_decl_tail c_enum_key c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl;
%type <node> enumlist enumlist_tail enumlist_item edecl_with_dox edecl;
%type <node> enumlist enumlist_item edecl_with_dox edecl;
/* C++ declarations */
%type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl cpp_alternate_rettype;
@ -3189,6 +3191,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Setattr($$,"throws",$4.throws);
Setattr($$,"throw",$4.throwf);
Setattr($$,"noexcept",$4.nexcept);
Setattr($$,"final",$4.final);
if ($5.val && $5.type) {
/* store initializer type as it might be different to the declared type */
SwigType *valuetype = NewSwigType($5.type);
@ -3266,6 +3269,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Setattr($$,"throws",$4.throws);
Setattr($$,"throw",$4.throwf);
Setattr($$,"noexcept",$4.nexcept);
Setattr($$,"final",$4.final);
if (!$9) {
if (Len(scanner_ccode)) {
String *code = Copy(scanner_ccode);
@ -3330,6 +3334,7 @@ c_decl_tail : SEMI {
Setattr($$,"throws",$3.throws);
Setattr($$,"throw",$3.throwf);
Setattr($$,"noexcept",$3.nexcept);
Setattr($$,"final",$3.final);
if ($4.bitfield) {
Setattr($$,"bitfield", $4.bitfield);
}
@ -3638,6 +3643,7 @@ c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
Setattr($$,"noexcept",$6.nexcept);
Setattr($$,"final",$6.final);
err = 0;
}
}
@ -4704,6 +4710,7 @@ cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
Setattr($$,"noexcept",$6.nexcept);
Setattr($$,"final",$6.final);
if (Len(scanner_ccode)) {
String *code = Copy(scanner_ccode);
Setattr($$,"code",code);
@ -4740,6 +4747,7 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
Setattr($$,"throws",$6.throws);
Setattr($$,"throw",$6.throwf);
Setattr($$,"noexcept",$6.nexcept);
Setattr($$,"final",$6.final);
if ($6.val)
Setattr($$,"value",$6.val);
if ($6.qualifier)
@ -4760,6 +4768,7 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
Setattr($$,"throws",$7.throws);
Setattr($$,"throw",$7.throwf);
Setattr($$,"noexcept",$7.nexcept);
Setattr($$,"final",$7.final);
if ($7.val)
Setattr($$,"value",$7.val);
if (Len(scanner_ccode)) {
@ -4941,6 +4950,7 @@ cpp_end : cpp_const SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
}
| cpp_const EQUAL default_delete SEMI {
Clear(scanner_ccode);
@ -4951,6 +4961,7 @@ cpp_end : cpp_const SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
}
| cpp_const LBRACE {
skip_balanced('{','}');
@ -4961,6 +4972,7 @@ cpp_end : cpp_const SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
}
;
@ -4973,6 +4985,7 @@ cpp_vend : cpp_const SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
}
| cpp_const EQUAL definetype SEMI {
Clear(scanner_ccode);
@ -4982,7 +4995,8 @@ cpp_vend : cpp_const SEMI {
$$.bitfield = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
}
| cpp_const LBRACE {
skip_balanced('{','}');
@ -4992,7 +5006,8 @@ cpp_vend : cpp_const SEMI {
$$.bitfield = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
}
;
@ -5210,6 +5225,7 @@ def_args : EQUAL definetype {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
}
| EQUAL definetype LBRACKET expr RBRACKET {
@ -5223,6 +5239,7 @@ def_args : EQUAL definetype {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
} else {
$$.val = NewStringf("%s[%s]",$2.val,$4.val);
}
@ -5236,6 +5253,7 @@ def_args : EQUAL definetype {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| COLON expr {
$$.val = 0;
@ -5245,6 +5263,7 @@ def_args : EQUAL definetype {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| empty {
$$.val = 0;
@ -5254,6 +5273,7 @@ def_args : EQUAL definetype {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
;
@ -6293,6 +6313,7 @@ definetype : { /* scanner_check_typedef(); */ } expr {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
scanner_ignore_typedef();
}
| default_delete {
@ -6319,6 +6340,7 @@ deleted_definition : DELETE_KW {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
;
@ -6333,6 +6355,7 @@ explicit_default : DEFAULT {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
;
@ -6351,21 +6374,31 @@ optional_ignored_defines
| empty
;
optional_ignored_define_after_comma
: empty
| COMMA
| COMMA constant_directive
;
/* Enum lists - any #define macros (constant directives) within the enum list are ignored. Trailing commas accepted. */
enumlist : enumlist_item optional_ignored_define_after_comma {
enumlist : enumlist_item {
Setattr($1,"_last",$1);
$$ = $1;
}
| enumlist_item enumlist_tail optional_ignored_define_after_comma {
set_nextSibling($1, $2);
Setattr($1,"_last",Getattr($2,"_last"));
Setattr($2,"_last",NULL);
| enumlist_item DOXYGENPOSTSTRING {
Setattr($1,"_last",$1);
set_comment($1, $2);
$$ = $1;
}
| enumlist_item COMMA enumlist {
if ($3) {
set_nextSibling($1, $3);
Setattr($1,"_last",Getattr($3,"_last"));
Setattr($3,"_last",NULL);
}
$$ = $1;
}
| enumlist_item COMMA DOXYGENPOSTSTRING enumlist {
if ($4) {
set_nextSibling($1, $4);
Setattr($1,"_last",Getattr($4,"_last"));
Setattr($4,"_last",NULL);
}
set_comment($1, $3);
$$ = $1;
}
| optional_ignored_defines {
@ -6373,17 +6406,6 @@ enumlist : enumlist_item optional_ignored_define_after_comma {
}
;
enumlist_tail : COMMA enumlist_item {
Setattr($2,"_last",$2);
$$ = $2;
}
| enumlist_tail COMMA enumlist_item {
set_nextSibling(Getattr($1,"_last"), $3);
Setattr($1,"_last",$3);
$$ = $1;
}
;
enumlist_item : optional_ignored_defines edecl_with_dox optional_ignored_defines {
$$ = $2;
}
@ -6396,19 +6418,6 @@ edecl_with_dox : edecl {
$$ = $2;
set_comment($2, $1);
}
| edecl DOXYGENPOSTSTRING {
$$ = $1;
set_comment($1, $2);
}
| DOXYGENPOSTSTRING edecl {
$$ = $2;
set_comment(previousNode, $1);
}
| DOXYGENPOSTSTRING edecl DOXYGENPOSTSTRING {
$$ = $2;
set_comment(previousNode, $1);
set_comment($2, $3);
}
;
edecl : identifier {
@ -6525,6 +6534,7 @@ valexpr : exprnum {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| WCHARCONST {
$$.val = NewString($1);
@ -6538,6 +6548,7 @@ valexpr : exprnum {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
/* grouping */
@ -6892,18 +6903,18 @@ virt_specifier_seq : OVERRIDE {
$$ = 0;
}
| FINAL {
$$ = 0;
$$ = NewString("1");
}
| FINAL OVERRIDE {
$$ = 0;
$$ = NewString("1");
}
| OVERRIDE FINAL {
$$ = 0;
$$ = NewString("1");
}
;
virt_specifier_seq_opt : virt_specifier_seq {
$$ = 0;
$$ = $1;
}
| empty {
$$ = 0;
@ -6914,31 +6925,37 @@ exception_specification : THROW LPAREN parms RPAREN {
$$.throws = $3;
$$.throwf = NewString("1");
$$.nexcept = 0;
$$.final = 0;
}
| NOEXCEPT {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = NewString("true");
$$.final = 0;
}
| virt_specifier_seq {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = $1;
}
| THROW LPAREN parms RPAREN virt_specifier_seq {
$$.throws = $3;
$$.throwf = NewString("1");
$$.nexcept = 0;
$$.final = $5;
}
| NOEXCEPT virt_specifier_seq {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = NewString("true");
$$.final = $2;
}
| NOEXCEPT LPAREN expr RPAREN {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = $3.val;
$$.final = 0;
}
;
@ -6946,6 +6963,7 @@ qualifiers_exception_specification : cv_ref_qualifier {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
$$.qualifier = $1.qualifier;
$$.refqualifier = $1.refqualifier;
}
@ -6968,6 +6986,7 @@ cpp_const : qualifiers_exception_specification {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
$$.qualifier = 0;
$$.refqualifier = 0;
}
@ -6980,6 +6999,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
if ($1.qualifier)
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
}
@ -6990,6 +7010,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
if ($1.qualifier)
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
}
@ -7001,6 +7022,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| LPAREN parms RPAREN LBRACE {
skip_balanced('{','}');
@ -7010,6 +7032,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| EQUAL definetype SEMI {
$$.have_parms = 0;
@ -7017,6 +7040,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| exception_specification EQUAL default_delete SEMI {
$$.have_parms = 0;
@ -7024,6 +7048,7 @@ ctor_end : cpp_const ctor_initializer SEMI {
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
if ($1.qualifier)
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
}

View file

@ -336,8 +336,13 @@ static std::string getPyDocType(Node *n, const_String_or_char_ptr lname = "") {
std::string type;
String *s = Swig_typemap_lookup("doctype", n, lname, 0);
if (!s) {
if (String *t = Getattr(n, "type"))
s = SwigType_str(t, "");
}
if (!s)
s = SwigType_str(Getattr(n, "type"), "");
return type;
if (Language::classLookup(s)) {
// In Python C++ namespaces are flattened, so remove all but last component

View file

@ -211,6 +211,7 @@
#define WARN_LANG_EXTEND_CONSTRUCTOR 522
#define WARN_LANG_EXTEND_DESTRUCTOR 523
#define WARN_LANG_EXPERIMENTAL 524
#define WARN_LANG_DIRECTOR_FINAL 525
/* -- Doxygen comments -- */

View file

@ -1873,38 +1873,56 @@ public:
typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
NIL);
// C++ destructor is wrapped by the Dispose method
// Note that the method name is specified in a typemap attribute called methodname
// C++ destructor is wrapped by the Finalize and Dispose methods
const char *tmap_method = derived ? "csdestruct_derived" : "csdestruct";
const String *tm = typemapExists(n, tmap_method, typemap_lookup_type);
if (tm) {
Swig_error(Getfile(tm), Getline(tm),
"A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
tmap_method, proxy_class_name);
}
tmap_method = "csfinalize";
tm = typemapExists(n, tmap_method, typemap_lookup_type);
if (tm) {
Swig_error(Getfile(tm), Getline(tm),
"A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
tmap_method, proxy_class_name);
}
tmap_method = derived ? "csdisposing_derived" : "csdisposing";
String *destruct = NewString("");
const String *tm = NULL;
attributes = NewHash();
String *destruct_methodname = NULL;
String *destruct_methodmodifiers = NULL;
const String *destruct_methodname = NULL;
const String *destruct_methodmodifiers = NULL;
const String *destruct_parameters = NULL;
if (derived) {
tm = typemapLookup(n, "csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct_derived:methodmodifiers");
tm = typemapLookup(n, "csdisposing_derived", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdisposing_derived:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing_derived:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:csdisposing_derived:parameters");
} else {
tm = typemapLookup(n, "csdestruct", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct:methodmodifiers");
tm = typemapLookup(n, "csdisposing", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdisposing:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:csdisposing:parameters");
}
if (tm && *Char(tm)) {
if (!destruct_methodname) {
Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in %s typemap for %s\n", tmap_method, proxy_class_name);
}
if (!destruct_methodmodifiers) {
Swig_error(Getfile(n), Getline(n),
"No methodmodifiers attribute defined in csdestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
"No methodmodifiers attribute defined in %s typemap for %s.\n", tmap_method, proxy_class_name);
}
if (!destruct_parameters)
destruct_parameters = empty_string;
}
// Emit the Finalize and Dispose methods
if (tm) {
// Finalize method
if (*Char(destructor_call)) {
Printv(proxy_class_def, typemapLookup(n, "csfinalize", typemap_lookup_type, WARN_NONE), NIL);
}
// Dispose method
// Finalize and Dispose methods
Printv(proxy_class_def, typemapLookup(n, derived ? "csdispose_derived" : "csdispose", typemap_lookup_type, WARN_NONE), NIL);
// Dispose(bool disposing) method
Printv(destruct, tm, NIL);
if (*Char(destructor_call))
Replaceall(destruct, "$imcall", destructor_call);
@ -1917,7 +1935,7 @@ public:
Printv(proxy_class_def, methodmods, NIL);
else
Printv(proxy_class_def, destruct_methodmodifiers, " ", derived ? "override" : "virtual", NIL);
Printv(proxy_class_def, " void ", destruct_methodname, "() ", destruct, "\n", NIL);
Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ") ", destruct, "\n", NIL);
}
}
if (*Char(interface_upcasts))
@ -3552,6 +3570,24 @@ public:
return tm;
}
/* -----------------------------------------------------------------------------
* typemapExists()
* n - for input only and must contain info for Getfile(n) and Getline(n) to work
* tmap_method - typemap method name
* type - typemap type to lookup
* returns found typemap or NULL if not found
* ----------------------------------------------------------------------------- */
const String *typemapExists(Node *n, const_String_or_char_ptr tmap_method, SwigType *type) {
Node *node = NewHash();
Setattr(node, "type", type);
Setfile(node, Getfile(n));
Setline(node, Getline(n));
const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
Delete(node);
return tm;
}
/* -----------------------------------------------------------------------------
* canThrow()
* Determine whether the code in the typemap can throw a C# exception.

View file

@ -3274,17 +3274,20 @@ private:
// attribute called »methodname«.
const String *tm = NULL;
String *dispose_methodname;
String *dispose_methodmodifiers;
const String *dispose_methodname;
const String *dispose_methodmodifiers;
const String *dispose_parameters;
attributes = NewHash();
if (derived) {
tm = lookupCodeTypemap(n, "ddispose_derived", typemap_lookup_type, WARN_NONE, attributes);
dispose_methodname = Getattr(attributes, "tmap:ddispose_derived:methodname");
dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose_derived:methodmodifiers");
dispose_parameters = Getattr(attributes, "tmap:ddispose_derived:parameters");
} else {
tm = lookupCodeTypemap(n, "ddispose", typemap_lookup_type, WARN_NONE, attributes);
dispose_methodname = Getattr(attributes, "tmap:ddispose:methodname");
dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose:methodmodifiers");
dispose_parameters = Getattr(attributes, "tmap:ddispose:parameters");
}
if (tm && *Char(tm)) {
@ -3298,6 +3301,8 @@ private:
"No methodmodifiers attribute defined in ddispose%s typemap for %s.\n",
(derived ? "_derived" : ""), proxy_class_name);
}
if (!dispose_parameters)
dispose_parameters = empty_string;
}
if (tm) {
@ -3324,7 +3329,7 @@ private:
Printv(body, methodmods, NIL);
else
Printv(body, dispose_methodmodifiers, (derived ? " override" : ""), NIL);
Printv(body, " void ", dispose_methodname, "() ", dispose_code, "\n", NIL);
Printv(body, " void ", dispose_methodname, "(", dispose_parameters, ") ", dispose_code, "\n", NIL);
}
}

View file

@ -188,7 +188,9 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
p = lp;
while (p) {
if (SwigType_isvarargs(Getattr(p, "type"))) {
// Mark the head of the ParmList that it has varargs
Setattr(l, "emit:varargs", lp);
//Printf(stdout, "setting emit:varargs %s ... %s +++ %s\n", Getattr(l, "emit:varargs"), Getattr(l, "type"), Getattr(p, "type"));
break;
}
p = nextSibling(p);
@ -329,7 +331,8 @@ int emit_num_required(ParmList *parms) {
/* -----------------------------------------------------------------------------
* emit_isvarargs()
*
* Checks if a function is a varargs function
* Checks if a ParmList is a parameter list containing varargs.
* This function requires emit_attach_parmmaps to have been called beforehand.
* ----------------------------------------------------------------------------- */
int emit_isvarargs(ParmList *p) {
@ -340,6 +343,28 @@ int emit_isvarargs(ParmList *p) {
return 0;
}
/* -----------------------------------------------------------------------------
* emit_isvarargs_function()
*
* Checks for varargs in a function/constructor (can be overloaded)
* ----------------------------------------------------------------------------- */
bool emit_isvarargs_function(Node *n) {
bool has_varargs = false;
Node *over = Getattr(n, "sym:overloaded");
if (over) {
for (Node *sibling = over; sibling; sibling = Getattr(sibling, "sym:nextSibling")) {
if (ParmList_has_varargs(Getattr(sibling, "parms"))) {
has_varargs = true;
break;
}
}
} else {
has_varargs = ParmList_has_varargs(Getattr(n, "parms")) ? true : false;
}
return has_varargs;
}
/* -----------------------------------------------------------------------------
* void emit_mark_vararg_parms()
*

View file

@ -125,6 +125,8 @@ class GO:public Language {
String *prefix_option;
// -fgo-pkgpath option.
String *pkgpath_option;
// Prefix for translating %import directive to import statements.
String *import_prefix;
// Whether to use a shared library.
bool use_shlib;
// Name of shared library to import.
@ -199,11 +201,12 @@ class GO:public Language {
public:
GO():package(NULL),
module(NULL),
cgo_flag(false),
cgo_flag(true),
gccgo_flag(false),
go_prefix(NULL),
prefix_option(NULL),
pkgpath_option(NULL),
import_prefix(NULL),
use_shlib(false),
soname(NULL),
intgo_type_size(0),
@ -269,6 +272,9 @@ private:
} else if (strcmp(argv[i], "-cgo") == 0) {
Swig_mark_arg(i);
cgo_flag = true;
} else if (strcmp(argv[i], "-no-cgo") == 0) {
Swig_mark_arg(i);
cgo_flag = false;
} else if (strcmp(argv[i], "-gccgo") == 0) {
Swig_mark_arg(i);
gccgo_flag = true;
@ -290,6 +296,15 @@ private:
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-import-prefix") == 0) {
if (argv[i + 1]) {
import_prefix = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-use-shlib") == 0) {
Swig_mark_arg(i);
use_shlib = true;
@ -740,7 +755,11 @@ private:
if (modname) {
if (!Getattr(go_imports, modname)) {
Setattr(go_imports, modname, modname);
Printv(f_go_imports, "import \"", modname, "\"\n", NULL);
Printv(f_go_imports, "import \"", NULL);
if (import_prefix) {
Printv(f_go_imports, import_prefix, "/", NULL);
}
Printv(f_go_imports, modname, "\"\n", NULL);
}
imported_package = modname;
saw_import = true;
@ -6979,9 +6998,11 @@ extern "C" Language *swig_go(void) {
const char * const GO::usage = "\
Go Options (available with -go)\n\
-cgo - Generate cgo input files\n\
-gccgo - Generate code for gccgo rather than 6g/8g\n\
-no-cgo - Do not generate cgo input files\n\
-gccgo - Generate code for gccgo rather than gc\n\
-go-pkgpath <p> - Like gccgo -fgo-pkgpath option\n\
-go-prefix <p> - Like gccgo -fgo-prefix option\n\
-import-prefix <p> - Prefix to add to %import directives\n\
-intgosize <s> - Set size of Go int type--32 or 64 bits\n\
-package <name> - Set name of the Go package to <name>\n\
-use-shlib - Force use of a shared library\n\

View file

@ -2035,16 +2035,19 @@ public:
String *destruct = NewString("");
const String *tm = NULL;
attributes = NewHash();
String *destruct_methodname = NULL;
String *destruct_methodmodifiers = NULL;
const String *destruct_methodname = NULL;
const String *destruct_methodmodifiers = NULL;
const String *destruct_parameters = NULL;
if (derived) {
tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:javadestruct_derived:parameters");
} else {
tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:javadestruct:parameters");
}
if (tm && *Char(tm)) {
if (!destruct_methodname) {
@ -2053,6 +2056,8 @@ public:
if (!destruct_methodmodifiers) {
Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
}
if (!destruct_parameters)
destruct_parameters = empty_string;
}
// Emit the finalize and delete methods
if (tm) {
@ -2073,7 +2078,7 @@ public:
Printv(proxy_class_def, methodmods, NIL);
else
Printv(proxy_class_def, destruct_methodmodifiers, NIL);
Printv(proxy_class_def, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ")", destructor_throws_clause, " ", destruct, "\n", NIL);
}
}
if (*Char(interface_upcasts))

View file

@ -1894,6 +1894,8 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
}
if (!checkAttribute(nn, "storage", "virtual"))
continue;
if (GetFlag(nn, "final"))
continue;
/* we need to add methods(cdecl) and destructor (to check for throw decl) */
int is_destructor = (Cmp(nodeType, "destructor") == 0);
if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
@ -2109,7 +2111,7 @@ int Language::classDirectorMethods(Node *n) {
Node *item = Getitem(vtable, i);
String *method = Getattr(item, "methodNode");
String *fqdname = Getattr(item, "fqdname");
if (GetFlag(method, "feature:nodirector"))
if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
continue;
String *wrn = Getattr(method, "feature:warnfilter");
@ -2198,6 +2200,16 @@ int Language::classDirector(Node *n) {
String *using_protected_members_code = NewString("");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
Node *nodeType = Getattr(ni, "nodeType");
if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
String *classtype = Getattr(n, "classtype");
SWIG_WARN_NODE_BEGIN(ni);
Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
SWIG_WARN_NODE_END(ni);
SetFlag(n, "feature:nodirector");
Delete(vtable);
Delete(using_protected_members_code);
return SWIG_OK;
}
bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
if (isNonVirtualProtectedAccess(ni)) {

View file

@ -970,11 +970,6 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
SWIG_exit(EXIT_SUCCESS); // Exit if we're in help mode
}
if (!tlm) {
Printf(stderr, "No target language specified\n");
return 1;
}
// Check all of the options to make sure we're cool.
// Don't check for an input file if -external-runtime is passed
Swig_check_options(external_runtime ? 0 : 1);
@ -1070,7 +1065,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
char *cfile = Char(input_file);
if (cfile && cfile[0] == '-') {
Printf(stderr, "Unable to find option or file '%s', ", input_file);
Printf(stderr, "use 'swig -help' for more information.\n");
Printf(stderr, "Use 'swig -help' for more information.\n");
} else {
Printf(stderr, "Unable to find file '%s'.\n", input_file);
}
@ -1079,6 +1074,13 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
}
}
if (!tlm) {
Printf(stderr, "No target language specified.\n");
Printf(stderr, "Use 'swig -help' for more information.\n");
SWIG_exit(EXIT_FAILURE);
}
if (!no_cpp) {
fclose(df);
Printf(fs, "%%include <swig.swg>\n");

View file

@ -752,7 +752,7 @@ public:
Printv(df->code,
"argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
"for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
Printv(df->code, dispatch, "\n", NIL);
Printv(df->code, dispatch, "\nfree(argv);\n", NIL);
Node *sibl = n;
while (Getattr(sibl, "sym:previousSibling"))
sibl = Getattr(sibl, "sym:previousSibling");

View file

@ -2187,7 +2187,7 @@ public:
* is_real_overloaded()
*
* Check if the function is overloaded, but not just have some
* siblings generated due to the original function have
* siblings generated due to the original function having
* default arguments.
* ------------------------------------------------------------ */
bool is_real_overloaded(Node *n) {
@ -2224,7 +2224,7 @@ public:
n = nn;
Parm *parms = Getattr(n, "parms");
bool varargs = parms ? emit_isvarargs(parms) : 0;
int varargs = parms ? emit_isvarargs(parms) : 0;
/* We prefer to explicitly list all parameters of the C function in the
generated Python code as this makes the function more convenient to use,
@ -2426,7 +2426,7 @@ public:
void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
String * meth_str = NewString("");
if (!kw) {
if (n && funpack) {
if (funpack) {
if (num_required == 0 && num_arguments == 0) {
Printf(meth_str, "\t { \"%s\", %s, METH_NOARGS, ", name, function);
} else if (num_required == 1 && num_arguments == 1) {
@ -2689,7 +2689,6 @@ public:
bool add_self = builtin_self && (!builtin_ctor || director_class);
bool builtin_getter = (builtin && GetFlag(n, "memberget"));
bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
bool over_varargs = false;
char const *self_param = builtin ? "self" : "SWIGUNUSEDPARM(self)";
char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
String *linkage = NewString("SWIGINTERN ");
@ -2765,22 +2764,7 @@ public:
}
}
if (overname) {
String *over_varargs_attr = Getattr(n, "python:overvarargs");
if (!over_varargs_attr) {
for (Node *sibling = n; sibling; sibling = Getattr(sibling, "sym:nextSibling")) {
if (emit_isvarargs(Getattr(sibling, "parms"))) {
over_varargs = true;
break;
}
}
over_varargs_attr = NewString(over_varargs ? "1" : "0");
for (Node *sibling = n; sibling; sibling = Getattr(sibling, "sym:nextSibling"))
Setattr(sibling, "python:overvarargs", over_varargs_attr);
}
if (Strcmp(over_varargs_attr, "0") != 0)
over_varargs = true;
}
bool over_varargs = emit_isvarargs_function(n);
int funpack = fastunpack && !varargs && !over_varargs && !allow_kwargs;
int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0);
@ -3608,11 +3592,7 @@ public:
Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname);
Printf(f_wrappers, tab2 "PyObject *module;\n", tm);
Printf(f_wrappers, tab2 "PyObject *d;\n");
if (fastunpack) {
Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
} else {
Printf(f_wrappers, tab2 "if (!PyArg_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
}
Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n");
Printf(f_wrappers, tab2 "if (!d) return NULL;\n");
Printf(f_wrappers, tab2 "%s\n", tm);
@ -3621,7 +3601,7 @@ public:
// Register the method in SwigMethods array
String *cname = NewStringf("%s_swigconstant", iname);
add_method(cname, cname, 0);
add_method(cname, cname, 0, 0, 1, 1, 1);
Delete(cname);
} else {
Printf(f_init, "%s\n", tm);
@ -4526,16 +4506,12 @@ public:
} else {
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
Printv(f_wrappers, " PyObject *obj;\n", NIL);
if (fastunpack) {
Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL);
} else {
Printv(f_wrappers, " if (!PyArg_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL);
}
Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL);
Printv(f_wrappers,
" SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct), ", SWIG_NewClientData(obj));\n", " return SWIG_Py_Void();\n", "}\n\n", NIL);
String *cname = NewStringf("%s_swigregister", class_name);
add_method(cname, cname, 0);
add_method(cname, cname, 0, 0, 1, 1, 1);
Delete(cname);
}
Delete(smart);

View file

@ -65,77 +65,38 @@ static String * getRTypeName(SwigType *t, int *outCount = NULL) {
*/
}
/*********************
Tries to get the name of the R class corresponding to the given type
e.g. struct A * is ARef, struct A** is ARefRef.
Now handles arrays, i.e. struct A[2]
****************/
/* --------------------------------------------------------------
* Tries to get the resolved name, with options of adding
* or removing a layer of references. Take care not
* to request both
* --------------------------------------------------------------*/
static String *getRClassName(String *retType, int /*addRef*/ = 1, int upRef=0) {
String *tmp = NewString("");
static String *getRClassName(String *retType, int deRef=0, int upRef=0) {
SwigType *resolved = SwigType_typedef_resolve_all(retType);
char *retName = Char(SwigType_manglestr(resolved));
int ispointer = SwigType_ispointer(resolved);
int isreference = SwigType_isreference(resolved);
if (upRef) {
Printf(tmp, "_p%s", retName);
} else{
Insert(tmp, 0, retName);
SwigType_add_pointer(resolved);
}
return tmp;
/*
#if 1
List *l = SwigType_split(retType);
int n = Len(l);
if(!l || n == 0) {
#ifdef R_SWIG_VERBOSE
if (debugMode)
Printf(stdout, "SwigType_split return an empty list for %s\n",
retType);
#endif
return(tmp);
}
String *el = Getitem(l, n-1);
char *ptr = Char(el);
if(strncmp(ptr, "struct ", 7) == 0)
ptr += 7;
Printf(tmp, "%s", ptr);
if(addRef) {
for(int i = 0; i < n; i++) {
if(Strcmp(Getitem(l, i), "p.") == 0 ||
Strncmp(Getitem(l, i), "a(", 2) == 0)
Printf(tmp, "Ref");
if (deRef) {
if (ispointer) {
SwigType_del_pointer(resolved);
}
}
#else
char *retName = Char(SwigType_manglestr(retType));
if(!retName)
return(tmp);
if(addRef) {
while(retName && strlen(retName) > 1 && strncmp(retName, "_p", 2) == 0) {
retName += 2;
Printf(tmp, "Ref");
if (isreference) {
SwigType_del_reference(resolved);
}
}
if(retName[0] == '_')
retName ++;
Insert(tmp, 0, retName);
#endif
return tmp;
*/
}
String *tmp = NewString("");
Insert(tmp, 0, Char(SwigType_manglestr(resolved)));
return(tmp);
}
/*********************
Tries to get the name of the R class corresponding to the given type
e.g. struct A * is ARef, struct A** is ARefRef.
Now handles arrays, i.e. struct A[2]
****************/
/* --------------------------------------------------------------
* Tries to get the name of the R class corresponding to the given type
* e.g. struct A * is ARef, struct A** is ARefRef.
* Now handles arrays, i.e. struct A[2]
* --------------------------------------------------------------*/
static String * getRClassNameCopyStruct(String *retType, int addRef) {
String *tmp = NewString("");
@ -188,12 +149,13 @@ static String * getRClassNameCopyStruct(String *retType, int addRef) {
}
/*********************************
Write the elements of a list to the File*, one element per line.
If quote is true, surround the element with "element".
This takes care of inserting a tab in front of each line and also
a comma after each element, except the last one.
**********************************/
/* -------------------------------------------------------------
* Write the elements of a list to the File*, one element per line.
* If quote is true, surround the element with "element".
* This takes care of inserting a tab in front of each line and also
* a comma after each element, except the last one.
* --------------------------------------------------------------*/
static void writeListByLine(List *l, File *out, bool quote = 0) {
int i, n = Len(l);
@ -222,9 +184,10 @@ R Options (available with -r)\n\
/************
Display the help for this module on the screen/console.
*************/
/* -------------------------------------------------------------
* Display the help for this module on the screen/console.
* --------------------------------------------------------------*/
static void showUsage() {
fputs(usage, stdout);
}
@ -238,10 +201,11 @@ static bool expandTypedef(SwigType *t) {
}
/*****
Determine whether we should add a .copy argument to the S function
that wraps/interfaces to the routine that returns the given type.
*****/
/* -------------------------------------------------------------
* Determine whether we should add a .copy argument to the S function
* that wraps/interfaces to the routine that returns the given type.
* --------------------------------------------------------------*/
static int addCopyParameter(SwigType *type) {
int ok = 0;
ok = Strncmp(type, "struct ", 7) == 0 || Strncmp(type, "p.struct ", 9) == 0;
@ -253,27 +217,15 @@ static int addCopyParameter(SwigType *type) {
}
static void replaceRClass(String *tm, SwigType *type) {
String *tmp = getRClassName(type);
String *tmp_base = getRClassName(type, 0);
String *tmp_ref = getRClassName(type, 1, 1);
String *tmp = getRClassName(type, 0, 0);
String *tmp_base = getRClassName(type, 1, 0);
String *tmp_ref = getRClassName(type, 0, 1);
Replaceall(tm, "$R_class", tmp);
Replaceall(tm, "$*R_class", tmp_base);
Replaceall(tm, "$&R_class", tmp_ref);
Delete(tmp); Delete(tmp_base); Delete(tmp_ref);
}
static bool getNumber(String *value, int* result) {
if(Char(value)) {
// Check the conversion processed the whole of value by having %c at
// the end of the format, and checking that only the first value is
// converted. We don't want to convert "3+7" -> 3.
char dummy;
if (sscanf(Char(value), "%i%c", result, &dummy) == 1)
return true;
}
return false;
}
class R : public Language {
public:
R();
@ -288,7 +240,8 @@ public:
int classDeclaration(Node *n);
int enumDeclaration(Node *n);
String *enumValue(Node *n);
virtual int enumvalueDeclaration(Node *n);
int membervariableHandler(Node *n);
int typedefHandler(Node *n);
@ -392,6 +345,8 @@ protected:
// Strings into which we cumulate the generated code that is to be written
//vto the files.
String *enum_values;
String *enum_def_calls;
String *sfile;
String *f_init;
String *s_classes;
@ -456,6 +411,8 @@ R::R() :
copyStruct(false),
memoryProfile(false),
aggressiveGc(false),
enum_values(0),
enum_def_calls(0),
sfile(0),
f_init(0),
s_classes(0),
@ -535,9 +492,10 @@ void R::addSMethodInfo(String *name, String *argType, int nargs) {
}
}
/*
Returns the name of the new routine.
*/
/* ----------------------------------------
* Returns the name of the new routine.
* ------------------------------------------ */
String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
String *funName = SwigType_manglestr(t);
@ -574,7 +532,6 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
for (i = 0; p; p = nextSibling(p), ++i) {
String *arg = Getattr(p, "name");
String *lname;
if (!arg && Cmp(Getattr(p, "type"), "void")) {
lname = NewStringf("arg%d", i+1);
Setattr(p, "name", lname);
@ -635,6 +592,9 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
}
Replaceall(tm, "$1", name);
Replaceall(tm, "$result", "r_tmp");
if (debugMode) {
Printf(stdout, "Calling Replace A: %s\n", Getattr(p,"type"));
}
replaceRClass(tm, Getattr(p,"type"));
Replaceall(tm,"$owner", "0");
Delete(lstr);
@ -756,6 +716,7 @@ void R::init() {
s_classes = NewString("");
s_init = NewString("");
s_init_routine = NewString("");
enum_def_calls = NewString("");
}
@ -771,14 +732,19 @@ int R::cDeclaration(Node *n) {
#endif
/**
Method from Language that is called to start the entire
processing off, i.e. the generation of the code.
It is called after the input has been read and parsed.
Here we open the output streams and generate the code.
***/
/* -------------------------------------------------------------
* Method from Language that is called to start the entire
* processing off, i.e. the generation of the code.
* It is called after the input has been read and parsed.
* Here we open the output streams and generate the code.
* ------------------------------------------------------------- */
int R::top(Node *n) {
String *module = Getattr(n, "name");
if (debugMode) {
Printf(stdout, "<Top> %s\n", module);
}
if(!Rpackage)
Rpackage = Copy(module);
if(!DllName)
@ -853,9 +819,9 @@ int R::top(Node *n) {
}
/*****************************************************
Write the generated code to the .S and the .c files.
****************************************************/
/* -------------------------------------------------------------
* Write the generated code to the .S and the .c files.
* ------------------------------------------------------------- */
int R::DumpCode(Node *n) {
String *output_filename = NewString("");
@ -878,6 +844,7 @@ int R::DumpCode(Node *n) {
Printf(scode, "%s\n\n", s_init);
Printf(scode, "%s\n\n", s_classes);
Printf(scode, "%s\n", sfile);
Printf(scode, "%s\n", enum_def_calls);
Delete(scode);
String *outfile = Getattr(n,"outfile");
@ -922,22 +889,23 @@ int R::DumpCode(Node *n) {
/*
We may need to do more.... so this is left as a
stub for the moment.
*/
/* -------------------------------------------------------------
* We may need to do more.... so this is left as a
* stub for the moment.
* -------------------------------------------------------------*/
int R::OutputClassAccessInfo(Hash *tb, File *out) {
int n = OutputClassMemberTable(tb, out);
OutputClassMethodsTable(out);
return n;
}
/************************************************************************
Currently this just writes the information collected about the
different methods of the C++ classes that have been processed
to the console.
This will be used later to define S4 generics and methods.
**************************************************************************/
/* -------------------------------------------------------------
* Currently this just writes the information collected about the
* different methods of the C++ classes that have been processed
* to the console.
* This will be used later to define S4 generics and methods.
* --------------------------------------------------------------*/
int R::OutputClassMethodsTable(File *) {
Hash *tb = ClassMethodsTable;
@ -966,20 +934,21 @@ int R::OutputClassMethodsTable(File *) {
}
/*
Iterate over the <class name>_set and <>_get
elements and generate the $ and $<- functions
that provide constrained access to the member
fields in these elements.
/* --------------------------------------------------------------
* Iterate over the <class name>_set and <>_get
* elements and generate the $ and $<- functions
* that provide constrained access to the member
* fields in these elements.
tb - a hash table that is built up in functionWrapper
as we process each membervalueHandler.
The entries are indexed by <class name>_set and
<class_name>_get. Each entry is a List *.
* tb - a hash table that is built up in functionWrapper
* as we process each membervalueHandler.
* The entries are indexed by <class name>_set and
* <class_name>_get. Each entry is a List *.
* out - the stram where the code is to be written. This is the S
* code stream as we generate only S code here.
* --------------------------------------------------------------*/
out - the stram where the code is to be written. This is the S
code stream as we generate only S code here..
*/
int R::OutputClassMemberTable(Hash *tb, File *out) {
List *keys = Keys(tb), *el;
@ -1019,17 +988,18 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
return n;
}
/*******************************************************************
Write the methods for $ or $<- for accessing a member field in an
struct or union (or class).
className - the name of the struct or union (e.g. Bar for struct Bar)
isSet - a logical value indicating whether the method is for
modifying ($<-) or accessing ($) the member field.
el - a list of length 2 * # accessible member elements + 1.
The first element is the name of the class.
The other pairs are member name and the name of the R function to access it.
out - the stream where we write the code.
********************************************************************/
/* --------------------------------------------------------------
* Write the methods for $ or $<- for accessing a member field in an
* struct or union (or class).
* className - the name of the struct or union (e.g. Bar for struct Bar)
* isSet - a logical value indicating whether the method is for
* modifying ($<-) or accessing ($) the member field.
* el - a list of length 2 * # accessible member elements + 1.
* The first element is the name of the class.
* The other pairs are member name and the name of the R function to access it.
* out - the stream where we write the code.
* --------------------------------------------------------------*/
int R::OutputMemberReferenceMethod(String *className, int isSet,
List *el, File *out) {
int numMems = Len(el), j;
@ -1153,15 +1123,16 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
return SWIG_OK;
}
/*******************************************************************
Write the methods for [ or [<- for accessing a member field in an
struct or union (or class).
className - the name of the struct or union (e.g. Bar for struct Bar)
el - a list of length 2 * # accessible member elements + 1.
The first element is the name of the class.
The other pairs are member name and the name of the R function to access it.
out - the stream where we write the code.
********************************************************************/
/* -------------------------------------------------------------
* Write the methods for [ or [<- for accessing a member field in an
* struct or union (or class).
* className - the name of the struct or union (e.g. Bar for struct Bar)
* el - a list of length 2 * # accessible member elements + 1.
* The first element is the name of the class.
* The other pairs are member name and the name of the R function to access it.
* out - the stream where we write the code.
* --------------------------------------------------------------*/
int R::OutputArrayMethod(String *className, List *el, File *out) {
int numMems = Len(el), j;
@ -1192,103 +1163,153 @@ int R::OutputArrayMethod(String *className, List *el, File *out) {
}
/************************************************************
Called when a enumeration is to be processed.
We want to call the R function defineEnumeration().
tdname is the typedef of the enumeration, i.e. giving its name.
*************************************************************/
/* -------------------------------------------------------------
* Called when a enumeration is to be processed.
* We want to call the R function defineEnumeration().
* tdname is the typedef of the enumeration, i.e. giving its name.
* --------------------------------------------------------------*/
int R::enumDeclaration(Node *n) {
if (getCurrentClass() && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
if (!ImportMode) {
if (getCurrentClass() && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
String *name = Getattr(n, "name");
String *tdname = Getattr(n, "tdname");
String *symname = Getattr(n, "sym:name");
/* Using name if tdname is empty. */
// TODO - deal with anonymous enumerations
// Previous enum code for R didn't wrap them
if (!symname || Getattr(n, "unnamedinstance"))
return SWIG_NOWRAP;
if(Len(tdname) == 0)
tdname = name;
// create mangled name for the enum
// This will have content if the %nspace feature is set on
// the input file
String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
String *ename;
if(!tdname || Strcmp(tdname, "") == 0) {
String *name = Getattr(n, "name");
ename = getRClassName(name);
if (debugMode) {
Node *current_class = getCurrentClass();
String *cl = NewString("");
if (current_class) {
cl = getEnumClassPrefix();
}
Printf(stdout, "enumDeclaration: %s, %s, %s, %s, %s\n", name, symname, nspace, ename, cl);
}
Delete(name);
// set up a call to create the R enum structure. The list of
// individual elements will be built in enum_code
enum_values = 0;
// Emit each enum item
Language::enumDeclaration(n);
return SWIG_OK;
Printf(enum_def_calls, "defineEnumeration(\"%s\",\n .values=c(%s))\n\n", ename, enum_values);
Delete(enum_values);
Delete(ename);
//Delete(symname);
}
return SWIG_OK;
}
/* -------------------------------------------------------------
* --------------------------------------------------------------*/
int R::enumvalueDeclaration(Node *n) {
if (getCurrentClass() && (cplus_mode != PUBLIC)) {
Printf(stdout, "evd: Not public\n");
return SWIG_NOWRAP;
}
String *mangled_tdname = SwigType_manglestr(tdname);
String *scode = NewString("");
Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
String *symname = Getattr(n, "sym:name");
String *value = Getattr(n, "value");
String *name = Getattr(n, "name");
Node *parent = parentNode(n);
String *parent_name = Getattr(parent, "name");
String *newsymname = 0;
String *tmpValue;
Printv(scode, "defineEnumeration('", mangled_tdname, "'",
",\n", tab8, tab8, tab4, ".values = c(\n", NIL);
Node *c;
int value = -1; // First number is zero
for (c = firstChild(n); c; c = nextSibling(c)) {
// const char *tag = Char(nodeType(c));
// if (Strcmp(tag,"cdecl") == 0) {
name = Getattr(c, "name");
String *val = Getattr(c, "enumvalue");
if(val && Char(val)) {
int inval;
if (!getNumber(val, &inval)) {
// Conversion failed - use the string value in val.
} else {
val = NULL;
value = inval;
}
} else {
val = NULL;
value++;
}
if (val != NULL) {
// This won't work in general, but will at least handle cases like (3)
// and 3+7, and when it doesn't work, it'll fail noisly rather than
// quietly using the wrong enum value like we used to.
if (!Strcmp(val, "true")) {
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, "TRUE",
nextSibling(c) ? ", " : "");
} else if (!Strcmp(val, "false")) {
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, "FALSE",
nextSibling(c) ? ", " : "");
} else {
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, val,
nextSibling(c) ? ", " : "");
}
} else {
Printf(scode, "%s%s%s'%s' = %d%s\n", tab8, tab8, tab8, name, value,
nextSibling(c) ? ", " : "");
}
// }
// Strange hack from parent method
if (value)
tmpValue = NewString(value);
else
tmpValue = NewString(name);
// Note that this is used in enumValue() amongst other places
Setattr(n, "value", tmpValue);
// Deal with enum values that are not int
int swigtype = SwigType_type(Getattr(n, "type"));
if (swigtype == T_BOOL) {
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
}
Printv(scode, "))", NIL);
Printf(sfile, "%s\n", scode);
if (GetFlag(parent, "scopedenum")) {
newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
symname = newsymname;
}
Delete(scode);
Delete(mangled_tdname);
{
// Wrap C/C++ enums with constant integers or use the typesafe enum pattern
SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
if (debugMode) {
Printf(stdout, "Setting type: %s\n", Copy(typemap_lookup_type));
}
Setattr(n, "type", typemap_lookup_type);
// Simple integer constants
// Note these are always generated for anonymous enums, no matter what enum_feature is specified
// Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
String *value = enumValue(n);
if (enum_values) {
Printf(enum_values, ",\n\"%s\" = %s", name, value);
} else {
enum_values = NewString("");
Printf(enum_values, "\"%s\" = %s", name, value);
}
Delete(value);
}
return SWIG_OK;
}
/*************************************************************
**************************************************************/
/* -------------------------------------------------------------
* Create accessor functions for variables.
* Does not create equivalent wrappers for enumerations,
* which are handled differently
* --------------------------------------------------------------*/
int R::variableWrapper(Node *n) {
String *name = Getattr(n, "sym:name");
if (debugMode) {
Printf(stdout, "variableWrapper %s\n", n);
}
processing_variable = 1;
Language::variableWrapper(n); // Force the emission of the _set and _get function wrappers.
processing_variable = 0;
SwigType *ty = Getattr(n, "type");
String *nodeType = nodeType(n);
int addCopyParam = addCopyParameter(ty);
//XXX
processType(ty, n);
if(!SwigType_isconst(ty)) {
if (nodeType && !Strcmp(nodeType, "enumitem")) {
/* special wrapper for enums - don't want the R _set, _get functions*/
if (debugMode) {
Printf(stdout, "variableWrapper enum branch\n");
}
} else if(!SwigType_isconst(ty)) {
Wrapper *f = NewWrapper();
Printf(f->def, "%s = \nfunction(value%s)\n{\n",
name, addCopyParam ? ", .copy = FALSE" : "");
@ -1306,6 +1327,12 @@ int R::variableWrapper(Node *n) {
return SWIG_OK;
}
/* -------------------------------------------------------------
* Creates accessor functions for class members.
* ToDo - this version depends on naming conventions and needs
* to be replaced.
* --------------------------------------------------------------*/
void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
int isSet) {
@ -1708,9 +1735,10 @@ void R::dispatchFunction(Node *n) {
DelWrapper(f);
}
/******************************************************************
/*--------------------------------------------------------------
* --------------------------------------------------------------*/
*******************************************************************/
int R::functionWrapper(Node *n) {
String *fname = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
@ -1752,6 +1780,9 @@ int R::functionWrapper(Node *n) {
SwigType *resolved =
SwigType_typedef_resolve_all(resultType);
if (expandTypedef(resolved)) {
if (debugMode) {
Printf(stdout, "Setting type: %s\n", resolved);
}
Setattr(p, "type", Copy(resolved));
}
}
@ -1764,18 +1795,18 @@ int R::functionWrapper(Node *n) {
SwigType_istypedef(type)) {
SwigType *resolved =
SwigType_typedef_resolve_all(type);
if (debugMode)
Printf(stdout, "<functionWrapper> resolved %s\n", Copy(unresolved_return_type));
if (expandTypedef(resolved)) {
type = Copy(resolved);
Setattr(n, "type", type);
}
}
if (debugMode)
Printf(stdout, "<functionWrapper> unresolved_return_type %s\n",
unresolved_return_type);
Printf(stdout, "<functionWrapper> unresolved_return_type %s\n", unresolved_return_type);
if(processing_member_access_function) {
if (debugMode)
Printf(stdout, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n",
fname, iname, member_name, class_name);
Printf(stdout, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n", fname, iname, member_name, class_name);
if(opaqueClassDeclaration)
return SWIG_OK;
@ -2067,14 +2098,12 @@ int R::functionWrapper(Node *n) {
/* Deal with the explicit return value. */
if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
SwigType *retType = Getattr(n, "type");
//Printf(stdout, "Return Value for %s, array? %s\n", retType, SwigType_isarray(retType) ? "yes" : "no");
/* if(SwigType_isarray(retType)) {
defineArrayAccessors(retType);
} */
Replaceall(tm,"$1", Swig_cresult_name());
Replaceall(tm,"$result", "r_ans");
if (debugMode){
Printf(stdout, "Calling replace D: %s, %s, %s\n", retType, n, tm);
}
replaceRClass(tm, retType);
if (GetFlag(n,"feature:new")) {
@ -2161,6 +2190,9 @@ int R::functionWrapper(Node *n) {
Delete(smartname);
}
}
if (debugMode) {
Printf(stdout, "Calling replace B: %s, %s, %s\n", Getattr(n, "type"), Getattr(n, "sym:name"), getNSpace());
}
replaceRClass(tm, Getattr(n, "type"));
Chop(tm);
}
@ -2196,6 +2228,9 @@ int R::functionWrapper(Node *n) {
tm = Swig_typemap_lookup("rtype", n, "", 0);
if(tm) {
SwigType *retType = Getattr(n, "type");
if (debugMode) {
Printf(stdout, "Calling replace C: %s\n", Copy(retType));
}
replaceRClass(tm, retType);
}
@ -2254,15 +2289,16 @@ int R::constantWrapper(Node *n) {
return SWIG_OK;
}
/*****************************************************
Add the specified routine name to the collection of
generated routines that are called from R functions.
This is used to register the routines with R for
resolving symbols.
/*--------------------------------------------------------------
* Add the specified routine name to the collection of
* generated routines that are called from R functions.
* This is used to register the routines with R for
* resolving symbols.
* rname - the name of the routine
* nargs - the number of arguments it expects.
* --------------------------------------------------------------*/
rname - the name of the routine
nargs - the number of arguments it expects.
******************************************************/
int R::addRegistrationRoutine(String *rname, int nargs) {
if(!registrationTable)
registrationTable = NewHash();
@ -2275,11 +2311,12 @@ int R::addRegistrationRoutine(String *rname, int nargs) {
return SWIG_OK;
}
/*****************************************************
Write the registration information to an array and
create the initialization routine for registering
these.
******************************************************/
/* -------------------------------------------------------------
* Write the registration information to an array and
* create the initialization routine for registering
* these.
* --------------------------------------------------------------*/
int R::outputRegistrationRoutines(File *out) {
int i, n;
if(!registrationTable)
@ -2322,11 +2359,11 @@ int R::outputRegistrationRoutines(File *out) {
/****************************************************************************
Process a struct, union or class declaration in the source code,
or an anonymous typedef struct
/* -------------------------------------------------------------
* Process a struct, union or class declaration in the source code,
* or an anonymous typedef struct
* --------------------------------------------------------------*/
*****************************************************************************/
//XXX What do we need to do here -
// Define an S4 class to refer to this.
@ -2433,9 +2470,7 @@ int R::classDeclaration(Node *n) {
class_member_set_functions = NULL;
}
if (Getattr(n, "has_destructor")) {
Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n",
getRClassName(Getattr(n, "name")),
getRClassName(Getattr(n, "name")));
Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name));
}
if(!opaque && !Strcmp(kind, "struct") && copyStruct) {
@ -2509,12 +2544,13 @@ int R::classDeclaration(Node *n) {
/***************************************************************
Create the C routines that copy an S object of the class given
by the given struct definition in Node *n to the C value
and also the routine that goes from the C routine to an object
of this S class.
****************************************************************/
/* -------------------------------------------------------------
* Create the C routines that copy an S object of the class given
* by the given struct definition in Node *n to the C value
* and also the routine that goes from the C routine to an object
* of this S class.
* --------------------------------------------------------------*/
/*XXX
Clean up the toCRef - make certain the names are correct for the types, etc.
in all cases.
@ -2609,13 +2645,14 @@ int R::generateCopyRoutines(Node *n) {
/*****
Called when there is a typedef to be invoked.
/* -------------------------------------------------------------
* Called when there is a typedef to be invoked.
*
* XXX Needs to be enhanced or split to handle the case where we have a
* typedef within a classDeclaration emission because the struct/union/etc.
* is anonymous.
* --------------------------------------------------------------*/
XXX Needs to be enhanced or split to handle the case where we have a
typedef within a classDeclaration emission because the struct/union/etc.
is anonymous.
******/
int R::typedefHandler(Node *n) {
SwigType *tp = Getattr(n, "type");
String *type = Getattr(n, "type");
@ -2639,12 +2676,13 @@ int R::typedefHandler(Node *n) {
/*********************
Called when processing a field in a "class", i.e. struct, union or
actual class. We set a state variable so that we can correctly
interpret the resulting functionWrapper() call and understand that
it is for a field element.
**********************/
/* --------------------------------------------------------------
* Called when processing a field in a "class", i.e. struct, union or
* actual class. We set a state variable so that we can correctly
* interpret the resulting functionWrapper() call and understand that
* it is for a field element.
* --------------------------------------------------------------*/
int R::membervariableHandler(Node *n) {
SwigType *t = Getattr(n, "type");
processType(t, n, NULL);
@ -2679,12 +2717,14 @@ String * R::runtimeCode() {
}
/**
Called when SWIG wants to initialize this
We initialize anythin we want here.
Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
Use Swig_mark_arg() to tell SWIG that it is understood and not to throw an error.
**/
/* -----------------------------------------------------------------------
* Called when SWIG wants to initialize this
* We initialize anythin we want here.
* Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
* Use Swig_mark_arg() to tell SWIG that it is understood and not to
* throw an error.
* --------------------------------------------------------------*/
void R::main(int argc, char *argv[]) {
init();
Preprocessor_define("SWIGR 1", 0);
@ -2767,10 +2807,10 @@ void R::main(int argc, char *argv[]) {
}
}
/*
Could make this work for String or File and then just store the resulting string
rather than the collection of arguments and argc.
*/
/* -----------------------------------------------------------------------
* Could make this work for String or File and then just store the resulting string
* rather than the collection of arguments and argc.
* ----------------------------------------------------------------------- */
int R::outputCommandLineArguments(File *out)
{
if(Argc < 1 || !Argv || !Argv[0])
@ -2796,18 +2836,17 @@ Language *swig_r(void) {
/*************************************************************************************/
/*
Needs to be reworked.
*/
/* -----------------------------------------------------------------------
* Needs to be reworked.
*----------------------------------------------------------------------- */
String * R::processType(SwigType *t, Node *n, int *nargs) {
//XXX Need to handle typedefs, e.g.
// a type which is a typedef to a function pointer.
SwigType *tmp = Getattr(n, "tdname");
if (debugMode)
Printf(stdout, "processType %s (tdname = %s)\n", Getattr(n, "name"), tmp);
Printf(stdout, "processType %s (tdname = %s)(SwigType = %s)\n", Getattr(n, "name"), tmp, Copy(t));
SwigType *td = t;
if (expandTypedef(t) &&
@ -2852,4 +2891,55 @@ String * R::processType(SwigType *t, Node *n, int *nargs) {
return NULL;
}
/*************************************************************************************/
/* -----------------------------------------------------------------------
* enumValue()
* This method will return a string with an enum value to use in from R when
* setting up an enum variable
* ------------------------------------------------------------------------ */
String *R::enumValue(Node *n) {
String *symname = Getattr(n, "sym:name");
String *value = Getattr(n, "value");
String *newsymname = 0;
Node *parent = parentNode(n);
symname = Getattr(n, "sym:name");
// parent enumtype has namespace mangled in
String *etype = Getattr(parent, "enumtype");
// we have to directly call the c wrapper function, as the
// R wrapper to the enum is designed to be used after the enum
// structures have been created on the R side. This means
// that we'll need to construct a .Call expression
// change the type for variableWrapper
if (debugMode) {
Printf(stdout, "<enumValue> type set: %s\n", etype);
}
Setattr(n, "type", etype);
if (!getCurrentClass()) {
newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
// Strange hack to change the name
Setattr(n, "name", Getattr(n, "value"));
Setattr(n, "sym:name", newsymname);
variableWrapper(n);
value = Swig_name_get(NSPACE_TODO, newsymname);
} else {
String *enumClassPrefix = getEnumClassPrefix();
newsymname = Swig_name_member(0, enumClassPrefix, symname);
Setattr(n, "name", Getattr(n, "value"));
Setattr(n, "sym:name", newsymname);
variableWrapper(n);
value = Swig_name_get(NSPACE_TODO, newsymname);
}
value = Swig_name_wrapper(value);
Replace(value, "_wrap", "R_swig", DOH_REPLACE_FIRST);
String *valuecall=NewString("");
Printv(valuecall, ".Call('", value, "',FALSE, PACKAGE='", Rpackage, "')", NIL);
Delete(value);
return valuecall;
}

View file

@ -383,7 +383,8 @@ List *SWIG_output_files();
void SWIG_library_directory(const char *);
int emit_num_arguments(ParmList *);
int emit_num_required(ParmList *);
int emit_isvarargs(ParmList *);
int emit_isvarargs(ParmList *p);
bool emit_isvarargs_function(Node *n);
void emit_attach_parmmaps(ParmList *, Wrapper *f);
void emit_mark_varargs(ParmList *l);
String *emit_action(Node *n);

View file

@ -109,6 +109,19 @@ static String *cpp_include(const_String_or_char_ptr fn, int sysfile) {
return s;
}
static int is_digits(const String *str) {
const char *s = Char(str);
int isdigits = (*s != 0);
while (*s) {
if (!isdigit(*s)) {
isdigits = 0;
break;
}
s++;
}
return isdigits;
}
List *Preprocessor_depend(void) {
return dependencies;
}
@ -1484,7 +1497,7 @@ String *Preprocessor_parse(String *s) {
Putc(c, id);
break;
case 42: /* Strip any leading space before preprocessor value */
case 42: /* Strip any leading space after the preprocessor directive (before preprocessor value) */
if (isspace(c)) {
if (c == '\n') {
Ungetc(c, s);
@ -1804,6 +1817,8 @@ String *Preprocessor_parse(String *s) {
Swig_error(Getfile(s), Getline(id), "cpp debug: level = %d, startlevel = %d\n", level, start_level);
} else if (Equal(id, "")) {
/* Null directive */
} else if (is_digits(id)) {
/* A gcc linemarker of the form '# linenum filename flags' (resulting from running gcc -E) */
} else {
/* Ignore unknown preprocessor directives which are inside an inactive
* conditional (github issue #394). */

View file

@ -254,3 +254,19 @@ int ParmList_has_defaultargs(ParmList *p) {
}
return 0;
}
/* ---------------------------------------------------------------------
* ParmList_has_varargs()
*
* Returns 1 if the parameter list passed in has varargs.
* Otherwise returns 0.
* ---------------------------------------------------------------------- */
int ParmList_has_varargs(ParmList *p) {
Parm *lp = 0;
while (p) {
lp = p;
p = nextSibling(p);
}
return lp ? SwigType_isvarargs(Getattr(lp, "type")) : 0;
}

View file

@ -1160,6 +1160,8 @@ static int look(Scanner *s) {
return SWIG_TOKEN_INT;
if (isdigit(c))
state = 84;
else if ((c == 'e') || (c == 'E'))
state = 82;
else if ((c == 'x') || (c == 'X'))
state = 85;
else if ((c == 'b') || (c == 'B'))
@ -1181,6 +1183,10 @@ static int look(Scanner *s) {
return SWIG_TOKEN_INT;
if (isdigit(c))
state = 84;
else if (c == '.')
state = 81;
else if ((c == 'e') || (c == 'E'))
state = 82;
else if ((c == 'l') || (c == 'L')) {
state = 87;
} else if ((c == 'u') || (c == 'U')) {

View file

@ -24,6 +24,7 @@ extern ParmList *CopyParmListMax(ParmList *, int count);
extern int ParmList_len(ParmList *);
extern int ParmList_numrequired(ParmList *);
extern int ParmList_has_defaultargs(ParmList *p);
extern int ParmList_has_varargs(ParmList *p);
/* Output functions */
extern String *ParmList_str(ParmList *);