diff options
Diffstat (limited to 'Source')
89 files changed, 2178 insertions, 3116 deletions
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h index c67ffeaba..2b63f034d 100644 --- a/Source/CParse/cparse.h +++ b/Source/CParse/cparse.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * cparse.h * * SWIG parser module. * ----------------------------------------------------------------------------- */ -#ifndef SWIG_CPARSE_H_ -#define SWIG_CPARSE_H_ +#ifndef SWIG_CPARSE_H +#define SWIG_CPARSE_H #include "swig.h" #include "swigwarn.h" @@ -43,7 +43,7 @@ extern "C" { extern void scanner_clear_rename(void); extern void scanner_set_location(String *file, int line); extern void scanner_set_main_input_file(String *file); - extern String *scanner_get_main_input_file(); + extern String *scanner_get_main_input_file(void); extern void Swig_cparse_follow_locators(int); extern void start_inline(char *, int); extern String *scanner_ccode; diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c index 44ac39bd3..2eb3f9774 100644 --- a/Source/CParse/cscanner.c +++ b/Source/CParse/cscanner.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * scanner.c * @@ -123,7 +123,7 @@ void Swig_cparse_cplusplusout(int v) { * Initialize buffers * ------------------------------------------------------------------------- */ -void scanner_init() { +void scanner_init(void) { scan = NewScanner(); Scanner_idstart(scan,"%"); scan_init = 1; @@ -331,6 +331,8 @@ static int yylook(void) { return COLON; case SWIG_TOKEN_DCOLONSTAR: return DSTAR; + case SWIG_TOKEN_LTEQUALGT: + return LESSEQUALGREATER; case SWIG_TOKEN_DCOLON: { @@ -354,6 +356,20 @@ static int yylook(void) { case SWIG_TOKEN_ELLIPSIS: return ELLIPSIS; + case SWIG_TOKEN_LLBRACKET: + do { + tok = Scanner_token(scan); + } while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0)); + if (tok <= 0) { + Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n"); + } + break; + + case SWIG_TOKEN_RRBRACKET: + /* Turn an unmatched ]] back into two ] - e.g. `a[a[0]]` */ + scanner_next_token(RBRACKET); + return RBRACKET; + /* Look for multi-character sequences */ case SWIG_TOKEN_RSTRING: @@ -528,11 +544,11 @@ void scanner_set_location(String *file, int line) { Scanner_set_location(scan,file,line-1); } -void scanner_check_typedef() { +void scanner_check_typedef(void) { check_typedef = 1; } -void scanner_ignore_typedef() { +void scanner_ignore_typedef(void) { check_typedef = 0; } @@ -540,7 +556,7 @@ void scanner_last_id(int x) { last_id = x; } -void scanner_clear_rename() { +void scanner_clear_rename(void) { rename_active = 0; } @@ -554,7 +570,7 @@ void scanner_set_main_input_file(String *file) { main_input_file = file; } -String *scanner_get_main_input_file() { +String *scanner_get_main_input_file(void) { return main_input_file; } @@ -573,6 +589,9 @@ int yylex(void) { scanner_init(); } + Delete(cparse_unknown_directive); + cparse_unknown_directive = NULL; + if (next_token) { l = next_token; next_token = 0; @@ -951,10 +970,8 @@ int yylex(void) { return (yylex()); } else { - Delete(cparse_unknown_directive); - cparse_unknown_directive = NULL; - /* SWIG directives */ + String *stext = 0; if (strcmp(yytext, "%module") == 0) return (MODULE); if (strcmp(yytext, "%insert") == 0) @@ -1041,7 +1058,7 @@ int yylex(void) { * the operator. */ cparse_unknown_directive = NewString(yytext); - String *stext = NewString(yytext + 1); + stext = NewString(yytext + 1); Seek(stext,0,SEEK_SET); Setfile(stext,cparse_file); Setline(stext,cparse_line); diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 8f5428915..7f685e84e 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * parser.y * @@ -13,18 +13,27 @@ * some point. Beware. * ----------------------------------------------------------------------------- */ -/* There are 6 known shift-reduce conflicts in this file, fail compilation if any - more are introduced. +/* There are a small number of known shift-reduce conflicts in this file, fail + compilation if any more are introduced. Please don't increase the number of the conflicts if at all possible. And if you really have no choice but to do it, make sure you clearly document each new conflict in this file. */ -%expect 6 +%expect 7 %{ #define yylex yylex +/* doh.h uses #pragma GCC poison with GCC to prevent direct calls to certain + * standard C library functions being introduced, but those cause errors due + * to checks like `#if defined YYMALLOC || defined malloc` in the bison + * template code. We can't easily arrange to include headers after that + * template code, so instead we disable the problematic poisoning for this + * file. + */ +#define DOH_NO_POISON_MALLOC_FREE + #include "swig.h" #include "cparse.h" #include "preprocessor.h" @@ -32,13 +41,16 @@ /* We do this for portability */ #undef alloca -#define alloca malloc +#define alloca Malloc + +#define YYMALLOC Malloc +#define YYFREE Free /* ----------------------------------------------------------------------------- * Externals * ----------------------------------------------------------------------------- */ -int yyparse(); +int yyparse(void); /* NEW Variables */ @@ -337,7 +349,7 @@ static String *make_name(Node *n, String *name,SwigType *decl) { } /* Generate an unnamed identifier */ -static String *make_unnamed() { +static String *make_unnamed(void) { unnamed++; return NewStringf("$unnamed%d$",unnamed); } @@ -862,7 +874,7 @@ static void add_typedef_name(Node *n, Node *declnode, String *oldName, Symtab *c /* If the class name is qualified. We need to create or lookup namespace entries */ -static Symtab *set_scope_to_global() { +static Symtab *set_scope_to_global(void) { Symtab *symtab = Swig_symbol_global_scope(); Swig_symbol_setscope(symtab); return symtab; @@ -1614,7 +1626,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) %token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT %token WARN %token LESSTHAN GREATERTHAN DELETE_KW DEFAULT -%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO +%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO LESSEQUALGREATER %token ARROW %token QUESTIONMARK %token TYPES PARMS @@ -1636,6 +1648,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) %left AND %left EQUALTO NOTEQUALTO %left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO +%left LESSEQUALGREATER %left LSHIFT RSHIFT %left PLUS MINUS %left STAR SLASH MODULO @@ -1700,9 +1713,10 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) %type <ptype> type_specifier primitive_type_list ; %type <node> fname stringtype; %type <node> featattr; -%type <node> lambda_introducer lambda_body; +%type <node> lambda_introducer lambda_body lambda_template; %type <pl> lambda_tail; %type <str> virt_specifier_seq virt_specifier_seq_opt; +%type <str> class_virt_specifier_opt; %% @@ -1782,7 +1796,7 @@ declaration : swig_directive { $$ = $1; } } else { Swig_error(cparse_file, cparse_line, "Syntax error in input(1).\n"); } - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } /* Out of class constructor/destructor declarations */ | c_constructor_decl { @@ -1939,6 +1953,9 @@ clear_directive : CLEAR tm_list SEMI { /* ------------------------------------------------------------ %constant name = value; %constant type name = value; + + Note: Source/Preprocessor/cpp.c injects `%constant X = Y;` for + each `#define X Y` so that's handled here too. ------------------------------------------------------------ */ constant_directive : CONSTANT identifier EQUAL definetype SEMI { @@ -2015,7 +2032,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI { } | CONSTANT error END { Swig_error(cparse_file,cparse_line,"Missing semicolon (';') after %%constant.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } ; @@ -2723,26 +2740,23 @@ typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace { /* typemap method type (lang,method) or (method) */ typemap_type : kwargs { - Hash *p; - String *name; - p = nextSibling($1); - if (p && (!Getattr(p,"value"))) { - /* this is the deprecated two argument typemap form */ - Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line, - "Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n"); - /* two argument typemap form */ - name = Getattr($1,"name"); - if (!name || (Strcmp(name,typemap_lang))) { - $$.method = 0; - $$.kwargs = 0; - } else { - $$.method = Getattr(p,"name"); - $$.kwargs = nextSibling(p); + String *name = Getattr($1, "name"); + Hash *p = nextSibling($1); + $$.method = name; + $$.kwargs = p; + if (Getattr($1, "value")) { + Swig_error(cparse_file, cparse_line, + "%%typemap method shouldn't have a value specified.\n"); + } + while (p) { + if (!Getattr(p, "value")) { + Swig_error(cparse_file, cparse_line, + "%%typemap attribute '%s' is missing its value. If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.\n", + Getattr(p, "name")); + /* Set to empty value to avoid segfaults later. */ + Setattr(p, "value", NewStringEmpty()); } - } else { - /* one-argument typemap-form */ - $$.method = Getattr($1,"name"); - $$.kwargs = p; + p = nextSibling(p); } } ; @@ -3375,7 +3389,7 @@ c_decl_tail : SEMI { } else { Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon (';').\n"); } - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } ; @@ -3407,17 +3421,17 @@ cpp_alternate_rettype : primitive_type { $$ = $1; } auto myFunc = [](int x, int y) throw() -> int { return x+y; }; auto six = [](int x, int y) { return x+y; }(4, 2); ------------------------------------------------------------ */ -cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer LPAREN parms RPAREN cpp_const lambda_body lambda_tail { +cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const lambda_body lambda_tail { $$ = new_node("lambda"); Setattr($$,"name",$3); add_symbols($$); } - | storage_class AUTO idcolon EQUAL lambda_introducer LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail { + | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail { $$ = new_node("lambda"); Setattr($$,"name",$3); add_symbols($$); } - | storage_class AUTO idcolon EQUAL lambda_introducer lambda_body lambda_tail { + | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template lambda_body lambda_tail { $$ = new_node("lambda"); Setattr($$,"name",$3); add_symbols($$); @@ -3430,6 +3444,13 @@ lambda_introducer : LBRACKET { } ; +lambda_template : LESSTHAN { + skip_balanced('<','>'); + $$ = 0; + } + | empty { $$ = 0; } + ; + lambda_body : LBRACE { skip_balanced('{','}'); $$ = 0; @@ -3669,7 +3690,7 @@ c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { } if (err) { Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } ; @@ -3688,7 +3709,11 @@ cpp_declaration : cpp_class_decl { $$ = $1; } /* A simple class/struct/union definition */ -cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { + +/* Note that class_virt_specifier_opt for supporting final classes introduces one shift-reduce conflict + with C style variable declarations, such as: struct X final; */ + +cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit LBRACE { String *prefix; List *bases = 0; Node *scope = 0; @@ -3696,10 +3721,10 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { $<node>$ = new_node("class"); Setline($<node>$,cparse_start_line); Setattr($<node>$,"kind",$2); - if ($4) { - Setattr($<node>$,"baselist", Getattr($4,"public")); - Setattr($<node>$,"protectedbaselist", Getattr($4,"protected")); - Setattr($<node>$,"privatebaselist", Getattr($4,"private")); + if ($5) { + Setattr($<node>$,"baselist", Getattr($5,"public")); + Setattr($<node>$,"protectedbaselist", Getattr($5,"protected")); + Setattr($<node>$,"privatebaselist", Getattr($5,"private")); } Setattr($<node>$,"allows_typedef","1"); @@ -3727,8 +3752,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { Setattr($<node>$, "Classprefix", $3); Classprefix = NewString($3); /* Deal with inheritance */ - if ($4) - bases = Swig_make_inherit_list($3,Getattr($4,"public"),Namespaceprefix); + if ($5) + bases = Swig_make_inherit_list($3,Getattr($5,"public"),Namespaceprefix); prefix = SwigType_istemplate_templateprefix($3); if (prefix) { String *fbase, *tbase; @@ -3808,7 +3833,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { Delattr($$, "prev_symtab"); /* Check for pure-abstract class */ - Setattr($$,"abstracts", pure_abstracts($7)); + Setattr($$,"abstracts", pure_abstracts($8)); /* This bit of code merges in a previously defined %extend directive (if any) */ { @@ -3824,12 +3849,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { scpname = Swig_symbol_qualifiedscopename(0); Setattr(classes, scpname, $$); - appendChild($$, $7); + appendChild($$, $8); if (am) Swig_extend_append_previous($$, am); - p = $9; + p = $10; if (p && !nscope_inner) { if (!cparse_cplusplus && currentOuterClass) appendChild(currentOuterClass, p); @@ -3853,8 +3878,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { } p = nextSibling(p); } - if ($9 && Cmp($1,"typedef") == 0) - add_typedef_name($$, $9, $3, cscope, scpname); + if ($10 && Cmp($1,"typedef") == 0) + add_typedef_name($$, $10, $3, cscope, scpname); Delete(scpname); if (cplus_mode != CPLUS_PUBLIC) { @@ -3876,12 +3901,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { if (cplus_mode == CPLUS_PRIVATE) { $$ = 0; /* skip private nested classes */ } else if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) { - $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9); + $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10); } else if (nscope_inner) { /* this is tricky */ /* we add the declaration in the original namespace */ if (Strcmp(nodeType(nscope_inner), "class") == 0 && cparse_cplusplus && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) - $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9); + $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10); appendChild(nscope_inner, $$); Swig_symbol_setscope(Getattr(nscope_inner, "symtab")); Delete(Namespaceprefix); @@ -3893,14 +3918,14 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { Swig_symbol_setscope(cscope); Delete(Namespaceprefix); Namespaceprefix = Swig_symbol_qualifiedscopename(0); - add_symbols($9); + add_symbols($10); if (nscope) { $$ = nscope; /* here we return recreated namespace tower instead of the class itself */ - if ($9) { - appendSibling($$, $9); + if ($10) { + appendSibling($$, $10); } } else if (!SwigType_istemplate(ty) && template_parameters == 0) { /* for template we need the class itself */ - $$ = $9; + $$ = $10; } } else { Delete(yyrename); @@ -3911,7 +3936,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { outer = Getattr(outer, "nested:outer"); appendSibling(outer, $$); Swig_symbol_setscope(cscope); /* declaration goes in the parent scope */ - add_symbols($9); + add_symbols($10); set_scope_to_global(); Delete(Namespaceprefix); Namespaceprefix = Swig_symbol_qualifiedscopename(0); @@ -3924,7 +3949,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { } else { yyrename = Copy(Getattr($<node>$, "class_rename")); add_symbols($$); - add_symbols($9); + add_symbols($10); Delattr($$, "class_rename"); } } @@ -4661,10 +4686,8 @@ cpp_members : cpp_member cpp_members { | include_directive { $$ = $1; } | empty { $$ = 0;} | error { - int start_line = cparse_line; - skip_decl(); - Swig_error(cparse_file,start_line,"Syntax error in input(3).\n"); - SWIG_exit(EXIT_FAILURE); + Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n"); + Exit(EXIT_FAILURE); } cpp_members { $$ = $3; } @@ -6736,10 +6759,6 @@ valexpr : exprsimple { $$ = $1; } $$ = $2; $$.val = NewStringf("&%s",$2.val); } - | LAND expr { - $$ = $2; - $$.val = NewStringf("&&%s",$2.val); - } | STAR expr { $$ = $2; $$.val = NewStringf("*%s",$2.val); @@ -6838,6 +6857,15 @@ exprcompound : expr PLUS expr { $$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3)); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } + | expr LESSEQUALGREATER expr { + $$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3)); + /* Really `<=>` returns one of `std::strong_ordering`, + * `std::partial_ordering` or `std::weak_ordering`, but we + * fake it by treating the return value as `int`. The main + * thing to do with the return value in this context is to + * compare it with 0, for which `int` does the job. */ + $$.type = T_INT; + } | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK { $$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5)); /* This may not be exactly right, but is probably good enough @@ -7039,6 +7067,14 @@ virt_specifier_seq_opt : virt_specifier_seq { } ; +class_virt_specifier_opt : FINAL { + $$ = NewString("1"); + } + | empty { + $$ = 0; + } + ; + exception_specification : THROW LPAREN parms RPAREN { $$.throws = $3; $$.throwf = NewString("1"); diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 3a9cfc72e..e6c1da4a6 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * templ.c * @@ -19,7 +19,7 @@ static int template_debug = 0; const char *baselists[3]; -void SwigType_template_init() { +void SwigType_template_init(void) { baselists[0] = "baselist"; baselists[1] = "protectedbaselist"; baselists[2] = "privatebaselist"; @@ -424,6 +424,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab if (tp) { Symtab *tsdecl = Getattr(n, "sym:symtab"); + String *tsname = Getattr(n, "sym:name"); while (p && tp) { String *name, *value, *valuestr, *tmp, *tmpr; int sz, i; @@ -465,11 +466,18 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist, i); - /* Replace(s,name,value, DOH_REPLACE_ID); */ - /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */ - SwigType_typename_replace(s, name, dvalue); - SwigType_typename_replace(s, tbase, iname); - /* Printf(stdout,"'%s'\n", s); */ + /* + The approach of 'trivially' replacing template arguments is kind of fragile. + In particular if types with similar name in different namespaces appear. + We will not replace template args if a type/class exists with the same + name which is not a template. + */ + Node * tynode = Swig_symbol_clookup(s, 0); + String *tyname = tynode ? Getattr(tynode, "sym:name") : 0; + if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) { + SwigType_typename_replace(s, name, dvalue); + SwigType_typename_replace(s, tbase, iname); + } } tmp = NewStringf("#%s", name); @@ -711,7 +719,7 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { int parms_len = ParmList_len(parms); int *priorities_row; max_possible_partials = Len(partials); - priorities_matrix = (int *)malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */ + priorities_matrix = (int *)Malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */ priorities_row = priorities_matrix; for (pi = First(partials); pi.item; pi = Next(pi)) { Parm *p = parms; @@ -909,7 +917,7 @@ success: Printf(stdout, " chosen template:'%s'\n", Getattr(n, "name")); } Delete(parms); - free(priorities_matrix); + Free(priorities_matrix); return n; } diff --git a/Source/CParse/util.c b/Source/CParse/util.c index 714bb2972..00863c035 100644 --- a/Source/CParse/util.c +++ b/Source/CParse/util.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * util.c * diff --git a/Source/DOH/base.c b/Source/DOH/base.c index f5e418893..8731a5f11 100644 --- a/Source/DOH/base.c +++ b/Source/DOH/base.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * base.c * @@ -18,10 +18,6 @@ * DohDelete() * ----------------------------------------------------------------------------- */ -#ifndef SWIG_DEBUG_DELETE -#define SWIG_DEBUG_DELETE 0 -#endif - void DohDelete(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; @@ -29,13 +25,8 @@ void DohDelete(DOH *obj) { if (!obj) return; if (!DohCheck(b)) { -#if SWIG_DEBUG_DELETE - fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n", stderr); - abort(); -#else - assert(0); -#endif - return; + fputs("Fatal internal error: Attempt to delete a non-DOH object.\n", stderr); + Exit(EXIT_FAILURE); } if (b->flag_intern) return; @@ -64,13 +55,8 @@ DOH *DohCopy(const DOH *obj) { if (!obj) return 0; if (!DohCheck(b)) { -#if SWIG_DEBUG_DELETE - fputs("DOH: Fatal error. Attempt to copy a non-doh object.\n", stderr); - abort(); -#else - assert(0); -#endif - return 0; + fputs("Fatal internal error: Attempt to copy a non-DOH object.\n", stderr); + Exit(EXIT_FAILURE); } objinfo = b->type; if (objinfo->doh_copy) { @@ -389,6 +375,18 @@ DOH *DohKeys(DOH *obj) { } /* ----------------------------------------------------------------------------- + * DohSortedKeys() + * ----------------------------------------------------------------------------- */ + +DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)) { + DOHList *keys = DohKeys(obj); + if (keys) { + DohSortList(keys, cmp); + } + return keys; +} + +/* ----------------------------------------------------------------------------- * DohGetInt() * ----------------------------------------------------------------------------- */ diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h index a948bc849..45a1f7fc8 100644 --- a/Source/DOH/doh.h +++ b/Source/DOH/doh.h @@ -4,22 +4,21 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doh.h * * This file describes of the externally visible functions in DOH. * ----------------------------------------------------------------------------- */ -#ifndef _DOH_H -#define _DOH_H +#ifndef SWIG_DOH_H +#define SWIG_DOH_H -#ifndef MACSWIG #include "swigconfig.h" -#endif -#include <stdio.h> #include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> /* Set the namespace prefix for DOH API functions. This can be used to control visibility of the functions in libraries */ @@ -53,6 +52,7 @@ #define DohSetattr DOH_NAMESPACE(Setattr) #define DohDelattr DOH_NAMESPACE(Delattr) #define DohKeys DOH_NAMESPACE(Keys) +#define DohSortedKeys DOH_NAMESPACE(SortedKeys) #define DohGetInt DOH_NAMESPACE(GetInt) #define DohGetDouble DOH_NAMESPACE(GetDouble) #define DohGetChar DOH_NAMESPACE(GetChar) @@ -122,6 +122,12 @@ #define DohIterator DOH_NAMESPACE(Iterator) #define DohFirst DOH_NAMESPACE(First) #define DohNext DOH_NAMESPACE(Next) +#define DohMalloc DOH_NAMESPACE(Malloc) +#define DohRealloc DOH_NAMESPACE(Realloc) +#define DohCalloc DOH_NAMESPACE(Calloc) +#define DohFree DOH_NAMESPACE(Free) +#define DohSetExitHandler DOH_NAMESPACE(SetExitHandler) +#define DohExit DOH_NAMESPACE(Exit) #endif #define DOH_MAJOR_VERSION 0 @@ -163,12 +169,11 @@ typedef struct { /* Memory management */ -#ifndef DohMalloc -#define DohMalloc malloc -#endif -#ifndef DohRealloc -#define DohRealloc realloc -#endif +/* Wrappers around malloc(), realloc() and calloc() which never return NULL. */ +extern void *DohMalloc(size_t size); +extern void *DohRealloc(void *ptr, size_t size); +extern void *DohCalloc(size_t n, size_t size); + #ifndef DohFree #define DohFree free #endif @@ -197,6 +202,7 @@ extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_c extern int DohDelattr(DOH *obj, const DOHString_or_char *name); extern int DohCheckattr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *value); extern DOH *DohKeys(DOH *obj); +extern DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)); extern int DohGetInt(DOH *obj, const DOHString_or_char *name); extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int); extern double DohGetDouble(DOH *obj, const DOHString_or_char *name); @@ -271,6 +277,24 @@ extern int DohGetMaxHashExpand(void); extern void DohSetmark(DOH *obj, int x); extern int DohGetmark(DOH *obj); +/* Set the function for DohExit() to call instead of exit(). + * + * The registered function can perform clean up, etc. It should simply + * return when done and then exit() will get called. Bear in mind that + * the handler function can be called after malloc() has failed, so it's + * a good idea for it to avoid allocating additional memory. + * + * The registered handler function is unregistered by DohExit() before calling + * it to avoid the potential for infinite loops. + * + * Note: This is sort of like C's atexit(), only for DohExit(). However + * only one function can be registered (setting a new function overrides the + * previous one) and the registered function is passed the exit status so can + * vary its actions based on that. + */ +extern void DohSetExitHandler(void (*new_handler)(int)); +extern void DohExit(int status); + /* ----------------------------------------------------------------------------- * Strings. * ----------------------------------------------------------------------------- */ @@ -422,6 +446,7 @@ extern void DohMemoryDebug(void); #define FileErrorDisplay DohFileErrorDisplay #define NewVoid DohNewVoid #define Keys DohKeys +#define SortedKeys DohSortedKeys #define Strcmp DohStrcmp #define Strncmp DohStrncmp #define Strstr DohStrstr @@ -440,6 +465,12 @@ extern void DohMemoryDebug(void); #define Next DohNext #define Iterator DohIterator #define SortList DohSortList +#define Malloc DohMalloc +#define Realloc DohRealloc +#define Calloc DohCalloc +#define Free DohFree +#define SetExitHandler DohSetExitHandler +#define Exit DohExit #endif #ifdef NIL @@ -448,5 +479,29 @@ extern void DohMemoryDebug(void); #define NIL (char *) NULL +/* Defines to allow use of poisoned identifiers. + * + * For DOH-internal use only! + */ +#define doh_internal_calloc calloc +#define doh_internal_exit exit +/* doh_internal_free not needed as Free() is a macro defined above. */ +#define doh_internal_malloc malloc +#define doh_internal_realloc realloc + +#if defined __GNUC__ && defined DOH_POISON +/* Use Malloc(), Realloc(), Calloc(), and Free() instead (which will exit with + * an error rather than return NULL). + */ +# ifndef DOH_NO_POISON_MALLOC_FREE +/* This works around bison's template checking if malloc and free are defined, + * which triggers GCC's poison checks. + */ +# pragma GCC poison malloc free +# endif +# pragma GCC poison realloc calloc +/* Use Exit() instead (which will remove output files on error). */ +# pragma GCC poison abort exit +#endif -#endif /* DOH_H */ +#endif /* SWIG_DOH_H */ diff --git a/Source/DOH/dohint.h b/Source/DOH/dohint.h index 87def9d3d..b637debd2 100644 --- a/Source/DOH/dohint.h +++ b/Source/DOH/dohint.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * dohint.h * * This file describes internally managed objects. * ----------------------------------------------------------------------------- */ -#ifndef _DOHINT_H -#define _DOHINT_H +#ifndef SWIG_DOHINT_H +#define SWIG_DOHINT_H #include "doh.h" @@ -128,4 +128,4 @@ typedef struct { extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */ extern void DohObjFree(DOH *ptr); /* Free a DOH object */ -#endif /* DOHINT_H */ +#endif /* SWIG_DOHINT_H */ diff --git a/Source/DOH/file.c b/Source/DOH/file.c index 96f700223..4bcf5d5e1 100644 --- a/Source/DOH/file.c +++ b/Source/DOH/file.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * file.c * @@ -35,7 +35,7 @@ typedef struct { * reference count of the underlying DOH objects. * ----------------------------------------------------------------------------- */ -static DOHList *open_files_list_instance() { +static DOHList *open_files_list_instance(void) { static DOHList *all_open_files = 0; if (!all_open_files) all_open_files = DohNewList(); @@ -73,7 +73,7 @@ static void open_files_list_remove(DohFile *f) { * Close all opened files, to be called on program termination * ----------------------------------------------------------------------------- */ -void DohCloseAllOpenFiles() { +void DohCloseAllOpenFiles(void) { int i; DOHList *all_open_files = open_files_list_instance(); for (i = 0; i < DohLen(all_open_files); i++) { @@ -291,10 +291,6 @@ DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) { return 0; f = (DohFile *) DohMalloc(sizeof(DohFile)); - if (!f) { - fclose(file); - return 0; - } if (newfiles) Append(newfiles, filename); f->filep = file; @@ -314,8 +310,6 @@ DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) { DOH *DohNewFileFromFile(FILE *file) { DohFile *f; f = (DohFile *) DohMalloc(sizeof(DohFile)); - if (!f) - return 0; f->filep = file; f->fd = 0; f->closeondel = 0; @@ -331,8 +325,6 @@ DOH *DohNewFileFromFile(FILE *file) { DOH *DohNewFileFromFd(int fd) { DohFile *f; f = (DohFile *) DohMalloc(sizeof(DohFile)); - if (!f) - return 0; f->filep = 0; f->fd = fd; f->closeondel = 0; diff --git a/Source/DOH/fio.c b/Source/DOH/fio.c index 77419008c..972fb23df 100644 --- a/Source/DOH/fio.c +++ b/Source/DOH/fio.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * fio.c * diff --git a/Source/DOH/hash.c b/Source/DOH/hash.c index c2bc3dd95..b9d501e3c 100644 --- a/Source/DOH/hash.c +++ b/Source/DOH/hash.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * hash.c * @@ -173,10 +173,7 @@ static void resize(Hash *h) { p = p + 2; } - table = (HashNode **) DohMalloc(newsize * sizeof(HashNode *)); - for (i = 0; i < newsize; i++) { - table[i] = 0; - } + table = (HashNode **) DohCalloc(newsize, sizeof(HashNode *)); /* Walk down the old set of nodes and re-place */ h->hashsize = newsize; diff --git a/Source/DOH/list.c b/Source/DOH/list.c index 8a96a9a60..cc619022d 100644 --- a/Source/DOH/list.c +++ b/Source/DOH/list.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * list.c * @@ -27,7 +27,6 @@ extern DohObjInfo DohListType; static void more(List *l) { l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *)); - assert(l->items); l->maxitems *= 2; } @@ -346,15 +345,10 @@ DohObjInfo DohListType = { #define MAXLISTITEMS 8 DOH *DohNewList(void) { - List *l; - int i; - l = (List *) DohMalloc(sizeof(List)); + List *l = (List *) DohMalloc(sizeof(List)); l->nitems = 0; l->maxitems = MAXLISTITEMS; - l->items = (void **) DohMalloc(l->maxitems * sizeof(void *)); - for (i = 0; i < MAXLISTITEMS; i++) { - l->items[i] = 0; - } + l->items = (void **) DohCalloc(l->maxitems, sizeof(void *)); l->file = 0; l->line = 0; return DohObjMalloc(&DohListType, l); diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c index 4a9494e85..f8081d3ae 100644 --- a/Source/DOH/memory.c +++ b/Source/DOH/memory.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * memory.c * @@ -14,6 +14,9 @@ #include "dohint.h" +#include <stdio.h> +#include <stdlib.h> + #ifndef DOH_POOL_SIZE #define DOH_POOL_SIZE 4194304 #endif @@ -45,13 +48,10 @@ static int pools_initialized = 0; * CreatePool() - Create a new memory pool * ---------------------------------------------------------------------- */ -static void CreatePool() { +static void CreatePool(void) { Pool *p = 0; p = (Pool *) DohMalloc(sizeof(Pool)); - assert(p); - p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize); - assert(p->ptr); - memset(p->ptr, 0, sizeof(DohBase) * PoolSize); + p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase)); p->len = PoolSize; p->blen = PoolSize * sizeof(DohBase); p->current = 0; @@ -65,7 +65,7 @@ static void CreatePool() { * InitPools() - Initialize the memory allocator * ---------------------------------------------------------------------- */ -static void InitPools() { +static void InitPools(void) { if (pools_initialized) return; CreatePool(); /* Create initial pool */ @@ -234,3 +234,59 @@ void DohMemoryDebug(void) { #endif } + +/* Function to call instead of exit(). */ +static void (*doh_exit_handler)(int) = NULL; + +void DohSetExitHandler(void (*new_handler)(int)) { + doh_exit_handler = new_handler; +} + +void DohExit(int status) { + if (doh_exit_handler) { + void (*handler)(int) = doh_exit_handler; + /* Unset the handler to avoid infinite loops if it tries to do something + * which calls DohExit() (e.g. calling Malloc() and that failing). + */ + doh_exit_handler = NULL; + handler(status); + } + doh_internal_exit(status); +} + +static void allocation_failed(size_t n, size_t size) { + /* Report and exit as directly as possible to try to avoid further issues due + * to lack of memory. */ + if (n == 1) { +#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L + fprintf(stderr, "Failed to allocate %zu bytes\n", size); +#else + fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size); +#endif + } else { +#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L + fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size); +#else + fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size); +#endif + } + DohExit(EXIT_FAILURE); +} + +void *DohMalloc(size_t size) { + void *p = doh_internal_malloc(size); + if (!p) allocation_failed(1, size); + return p; +} + +void *DohRealloc(void *ptr, size_t size) { + void *p = doh_internal_realloc(ptr, size); + if (!p) allocation_failed(1, size); + return p; +} + +void *DohCalloc(size_t n, size_t size) { + void *p = doh_internal_calloc(n, size); + if (!p) allocation_failed(n, size); + return p; +} diff --git a/Source/DOH/string.c b/Source/DOH/string.c index 093330b89..c86cab0be 100644 --- a/Source/DOH/string.c +++ b/Source/DOH/string.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * string.c * @@ -180,19 +180,27 @@ static int String_hash(DOH *so) { if (s->hashkey >= 0) { return s->hashkey; } else { - char *c = s->str; + /* We use the djb2 hash function: https://theartincode.stanis.me/008-djb2/ + * + * One difference is we use initial seed 0. It seems the usual seed value + * is intended to help spread out hash values, which is beneficial if + * linear probing is used but DOH Hash uses a chain of buckets instead, and + * grouped hash values are probably more cache friendly. In tests using + * 0 seems slightly faster anyway. + */ + const char *c = s->str; unsigned int len = s->len > 50 ? 50 : s->len; unsigned int h = 0; unsigned int mlen = len >> 2; unsigned int i = mlen; for (; i; --i) { - h = (h << 5) + *(c++); - h = (h << 5) + *(c++); - h = (h << 5) + *(c++); - h = (h << 5) + *(c++); + h = h + (h << 5) + *(c++); + h = h + (h << 5) + *(c++); + h = h + (h << 5) + *(c++); + h = h + (h << 5) + *(c++); } for (i = len - (mlen << 2); i; --i) { - h = (h << 5) + *(c++); + h = h + (h << 5) + *(c++); } h &= 0x7fffffff; s->hashkey = (int)h; @@ -229,7 +237,6 @@ static void DohString_append(DOH *so, const DOHString_or_char *str) { if (newlen >= newmaxsize - 1) newmaxsize = newlen + 1; s->str = (char *) DohRealloc(s->str, newmaxsize); - assert(s->str); s->maxsize = newmaxsize; } tc = s->str; @@ -296,7 +303,6 @@ static int String_insert(DOH *so, int pos, DOH *str) { while (s->maxsize <= s->len + len) { int newsize = 2 * s->maxsize; s->str = (char *) DohRealloc(s->str, newsize); - assert(s->str); s->maxsize = newsize; } memmove(s->str + pos + len, s->str + pos, (s->len - pos)); @@ -424,7 +430,6 @@ static int String_write(DOH *so, const void *buffer, int len) { newlen = s->sp + len + 1; if (newlen > s->maxsize) { s->str = (char *) DohRealloc(s->str, newlen); - assert(s->str); s->maxsize = newlen; s->len = s->sp + len; } @@ -517,7 +522,6 @@ static int String_putc(DOH *so, int ch) { if (len > (maxsize - 2)) { maxsize *= 2; tc = (char *) DohRealloc(tc, maxsize); - assert(tc); s->maxsize = (int) maxsize; s->str = tc; } @@ -614,11 +618,13 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) { if (!s) return 0; if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) { - s += tokenlen; + /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ + ++s; continue; } if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) { - s += tokenlen; + /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ + ++s; continue; } return s; @@ -628,12 +634,14 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) { static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) { + (void)tokenlen; while (s) { s = strstr(s, token); if (!s) return 0; if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) { - s += tokenlen; + /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ + ++s; continue; } return s; @@ -648,7 +656,8 @@ static char *match_identifier_end(char *base, char *s, char *token, int tokenlen if (!s) return 0; if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) { - s += tokenlen; + /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ + ++s; continue; } return s; @@ -663,7 +672,8 @@ static char *match_number_end(char *base, char *s, char *token, int tokenlen) { if (!s) return 0; if (isdigit((int) *(s + tokenlen))) { - s += tokenlen; + /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ + ++s; continue; } return s; @@ -923,7 +933,6 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co newsize *= 2; ns = (char *) DohMalloc(newsize); - assert(ns); t = ns; s = first; diff --git a/Source/DOH/void.c b/Source/DOH/void.c index 6111a8c49..bbecca21b 100644 --- a/Source/DOH/void.c +++ b/Source/DOH/void.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * void.c * diff --git a/Source/Doxygen/doxycommands.h b/Source/Doxygen/doxycommands.h index b5d65af65..782b6ab94 100644 --- a/Source/Doxygen/doxycommands.h +++ b/Source/Doxygen/doxycommands.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxycommands.h * @@ -44,6 +44,8 @@ const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionInd const char *simpleCommands[] = { // the first line are escaped chars, except \~, which is a language ID command. "n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::", + // Member groups, which we currently ignore. + "{", "}", "endcond", "callgraph", "callergraph", "showinitializer", "hideinitializer", "internal", "nosubgrouping", "public", "publicsection", "private", "privatesection", diff --git a/Source/Doxygen/doxyentity.cxx b/Source/Doxygen/doxyentity.cxx index 8b9f65736..6fe97dd36 100644 --- a/Source/Doxygen/doxyentity.cxx +++ b/Source/Doxygen/doxyentity.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxyentity.cxx * diff --git a/Source/Doxygen/doxyentity.h b/Source/Doxygen/doxyentity.h index 93737e604..e475141a3 100644 --- a/Source/Doxygen/doxyentity.h +++ b/Source/Doxygen/doxyentity.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxyentity.h * * Part of the Doxygen comment translation module of SWIG. * ----------------------------------------------------------------------------- */ -#ifndef DOXYGENENTITY_H_ -#define DOXYGENENTITY_H_ +#ifndef SWIG_DOXYENTITY_H +#define SWIG_DOXYENTITY_H #include <string> #include <list> diff --git a/Source/Doxygen/doxyparser.cxx b/Source/Doxygen/doxyparser.cxx index db0fca9f5..0c445f1a0 100644 --- a/Source/Doxygen/doxyparser.cxx +++ b/Source/Doxygen/doxyparser.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxyparser.cxx * ----------------------------------------------------------------------------- */ diff --git a/Source/Doxygen/doxyparser.h b/Source/Doxygen/doxyparser.h index e692729ce..a60446517 100644 --- a/Source/Doxygen/doxyparser.h +++ b/Source/Doxygen/doxyparser.h @@ -4,13 +4,13 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxyparser.h * ----------------------------------------------------------------------------- */ -#ifndef DOXYGENPARSER_H_ -#define DOXYGENPARSER_H_ +#ifndef SWIG_DOXYPARSER_H +#define SWIG_DOXYPARSER_H #include <string> #include <list> #include <map> @@ -238,7 +238,7 @@ private: * Method for Adding a Simple Command * Format: @command * Plain commands, such as newline etc, they contain no other data - * \n \\ \@ \& \$ \# \< \> \% + * \n \\ \@ \& \$ \# \< \> \% \{ \} */ void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList); /* diff --git a/Source/Doxygen/doxytranslator.cxx b/Source/Doxygen/doxytranslator.cxx index fb21de75c..a638717ec 100644 --- a/Source/Doxygen/doxytranslator.cxx +++ b/Source/Doxygen/doxytranslator.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxytranslator.cxx * diff --git a/Source/Doxygen/doxytranslator.h b/Source/Doxygen/doxytranslator.h index a72a31df6..f0d3b1b06 100644 --- a/Source/Doxygen/doxytranslator.h +++ b/Source/Doxygen/doxytranslator.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * doxytranslator.h * @@ -12,8 +12,8 @@ * systems. * ----------------------------------------------------------------------------- */ -#ifndef DOXYGENTRANSLATOR_H_ -#define DOXYGENTRANSLATOR_H_ +#ifndef SWIG_DOXYTRANSLATOR_H +#define SWIG_DOXYTRANSLATOR_H #include "swig.h" #include "doxyentity.h" diff --git a/Source/Doxygen/javadoc.cxx b/Source/Doxygen/javadoc.cxx index eafa57317..a1406b230 100644 --- a/Source/Doxygen/javadoc.cxx +++ b/Source/Doxygen/javadoc.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * javadoc.cxx * ----------------------------------------------------------------------------- */ @@ -463,7 +463,11 @@ void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translate if (it != tag.entityList.end()) title = it->data; - translatedComment += "<img src=" + file; + translatedComment += "<img src="; + if (file.size() >= 2 && file[0] == '"' && file[file.size() - 1] == '"') + translatedComment += file; + else + translatedComment += "\"" + file + "\""; if (title.size()) translatedComment += " alt=" + title; diff --git a/Source/Doxygen/javadoc.h b/Source/Doxygen/javadoc.h index 6feff5295..d2c956c9d 100644 --- a/Source/Doxygen/javadoc.h +++ b/Source/Doxygen/javadoc.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * javadoc.h * * Module to return documentation for nodes formatted for JavaDoc * ----------------------------------------------------------------------------- */ -#ifndef JAVADOCCONVERTER_H_ -#define JAVADOCCONVERTER_H_ +#ifndef SWIG_JAVADOC_H +#define SWIG_JAVADOC_H #include "doxytranslator.h" #include <map> diff --git a/Source/Doxygen/pydoc.cxx b/Source/Doxygen/pydoc.cxx index 7b47a814c..28f6051a7 100644 --- a/Source/Doxygen/pydoc.cxx +++ b/Source/Doxygen/pydoc.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * pydoc.cxx * diff --git a/Source/Doxygen/pydoc.h b/Source/Doxygen/pydoc.h index 19885276f..880ee3069 100644 --- a/Source/Doxygen/pydoc.h +++ b/Source/Doxygen/pydoc.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * pydoc.h * * Module to return documentation for nodes formatted for PyDoc * ----------------------------------------------------------------------------- */ -#ifndef PYDOCCONVERTER_H_ -#define PYDOCCONVERTER_H_ +#ifndef SWIG_PYDOC_H +#define SWIG_PYDOC_H #include <list> #include <string> diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index e33ca467e..fc379c014 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigwarn.h * @@ -22,8 +22,8 @@ * This file is used as the input for generating Lib/swigwarn.swg. * ----------------------------------------------------------------------------- */ -#ifndef SWIGWARN_H_ -#define SWIGWARN_H_ +#ifndef SWIG_SWIGWARN_H +#define SWIG_SWIGWARN_H #define WARN_NONE 0 @@ -52,7 +52,7 @@ #define WARN_DEPRECATED_NAME 121 #define WARN_DEPRECATED_NOEXTERN 122 #define WARN_DEPRECATED_NODEFAULT 123 -#define WARN_DEPRECATED_TYPEMAP_LANG 124 +/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG 124 */ #define WARN_DEPRECATED_INPUT_FILE 125 #define WARN_DEPRECATED_NESTED_WORKAROUND 126 @@ -147,6 +147,7 @@ #define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */ #define WARN_IGNORE_OPERATOR_DELARR 395 /* delete [] */ #define WARN_IGNORE_OPERATOR_REF 396 /* operator *() */ +#define WARN_IGNORE_OPERATOR_LTEQUALGT 397 /* <=> */ /* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */ @@ -163,6 +164,7 @@ #define WARN_TYPEMAP_SWIGTYPE 452 /* No longer issued */ #define WARN_TYPEMAP_APPLY_UNDEF 453 #define WARN_TYPEMAP_SWIGTYPELEAK 454 +#define WARN_TYPEMAP_WCHARLEAK 455 #define WARN_TYPEMAP_IN_UNDEF 460 #define WARN_TYPEMAP_OUT_UNDEF 461 @@ -279,7 +281,7 @@ #define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824 #define WARN_JAVA_NO_DIRECTORCONNECT_ATTR 825 #define WARN_JAVA_NSPACE_WITHOUT_PACKAGE 826 -#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847 +#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827 /* please leave 810-829 free for Java */ diff --git a/Source/Makefile.am b/Source/Makefile.am index 5cfb88839..095c5d4ea 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -6,8 +6,6 @@ AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2 SOURCE_DIR=$(top_srcdir)/Source BUILD_SOURCE_DIR=$(top_builddir)/Source -SWIG_CXX_DEFS = @SWILL@ - AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \ -I$(BUILD_SOURCE_DIR)/CParse \ -I$(SOURCE_DIR)/Include \ @@ -18,7 +16,7 @@ AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \ -I$(SOURCE_DIR)/Swig \ -I$(SOURCE_DIR)/Modules -AM_CXXFLAGS = $(SWIG_CXX_DEFS) +AM_CXXFLAGS = AM_YFLAGS = -d @@ -46,7 +44,6 @@ eswig_SOURCES = CParse/cscanner.c \ Doxygen/pydoc.cxx \ Doxygen/pydoc.h \ Modules/allocate.cxx \ - Modules/browser.cxx \ Modules/contract.cxx \ Modules/csharp.cxx \ Modules/d.cxx \ @@ -98,7 +95,6 @@ eswig_SOURCES = CParse/cscanner.c \ Swig/wrapfunc.c bin_PROGRAMS = eswig -eswig_LDADD = @SWIGLIBS@ # Override the link stage to avoid using Libtool CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 7d567395c..0e1262f83 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * allocate.cxx * @@ -197,7 +197,7 @@ class Allocate:public Dispatcher { // Found a polymorphic method. // Mark the polymorphic method, in case the virtual keyword was not used. Setattr(n, "storage", "virtual"); - if (!Getattr(b, "feature:interface")) { // interface implementation neither hides nor overrides + if (!GetFlag(b, "feature:interface")) { // interface implementation neither hides nor overrides if (both_have_public_access || both_have_protected_access) { if (!is_non_public_base(inclass, b)) Setattr(n, "override", base); // Note C# definition of override, ie access must be the same diff --git a/Source/Modules/browser.cxx b/Source/Modules/browser.cxx deleted file mode 100644 index 217b40a7e..000000000 --- a/Source/Modules/browser.cxx +++ /dev/null @@ -1,421 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. - * - * browser.cxx - * - * A web-base parse tree browser using SWILL. This is an optional - * feature that's normally disabled. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" - -#ifdef SWIG_SWILL -extern "C" { -#include "swill.h" -} static FILE *out = 0; -static Node *view_top = 0; - -class Browser:public Dispatcher { - void show_checkbox(Node *t, Node *n) { - int v = 0; - if (Getmeta(n, "visible")) { - v = 1; - } - if (v) { - Printf(out, "<a name=\"n%p\"></a>[<a href=\"hide.html?node=%p&hn=%p#n%p\">-</a>] ", n, t, n, n); - } else { - Printf(out, "<a name=\"n%p\"></a>[<a href=\"show.html?node=%p&hn=%p#n%p\">+</a>] ", n, t, n, n); - } - } - void show_attributes(Node *obj) { - if (!Getmeta(obj, "visible")) - return; - String *os = NewString(""); - String *k; - Iterator ki; - ki = First(obj); - while (ki.key) { - k = ki.key; - if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) || - (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) { - /* Do nothing */ - } else if (Cmp(k, "parms") == 0) { - String *o = NewString(""); - Printf(o, "%s", ParmList_protostr(Getattr(obj, k))); - Replaceall(o, "&", "&"); - Replaceall(o, "<", "<"); - Replaceall(o, ">", ">"); - Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - %s\n", Getattr(obj, k), k, o); - Delete(o); - } else { - DOH *o; - char *trunc = ""; - if (DohIsString(Getattr(obj, k))) { - o = Str(Getattr(obj, k)); - if (Len(o) > 70) { - trunc = "..."; - } - Replaceall(o, "&", "&"); - Replaceall(o, "<", "<"); - Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc); - Delete(o); - } else { - Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k)); - } - } - ki = Next(ki); - } - Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os)); - Delete(os); - } - -public: - virtual int emit_one(Node *n) { - char *tag = Char(nodeType(n)); - char *file = Char(Getfile(n)); - int line = Getline(n); - char *name = GetChar(n, "name"); - - show_checkbox(view_top, n); - Printf(out, "<b><a href=\"index.html?node=%p\">%s</a></b>", n, tag); - if (name) { - Printf(out, " (%s)", name); - } - Printf(out, ". %s:%d\n", file, line); - Printf(out, "<br>"); - Dispatcher::emit_one(n); - return SWIG_OK; - } - virtual int emit_children(Node *n) { - if (Getmeta(n, "visible")) { - Printf(out, "<blockquote>\n"); - Dispatcher::emit_children(n); - Printf(out, "</blockquote>\n"); - } - return SWIG_OK; - } - virtual int defaultHandler(Node *n) { - show_attributes(n); - return SWIG_OK; - } - virtual int top(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - virtual int includeDirective(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - virtual int importDirective(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - - virtual int extendDirective(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - virtual int classDeclaration(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - - virtual int templateDeclaration(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - - virtual int lambdaDeclaration(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - - virtual int enumDeclaration(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - virtual int typemapDirective(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - virtual int namespaceDeclaration(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - virtual int usingDeclaration(Node *n) { - show_attributes(n); - emit_children(n); - return SWIG_OK; - } - -}; - -static int browser_exit = 0; -static Node *tree_top = 0; -static Browser *browse = 0; - -/* ---------------------------------------------------------------------- - * exit_handler() - Force the browser to exit - * ---------------------------------------------------------------------- */ - -void exit_handler(FILE *f) { - browser_exit = 1; - Printf(f, "Terminated.\n"); -} - -/* ---------------------------------------------------------------------- - * node_handler() - Generate information about a specific node - * ---------------------------------------------------------------------- */ - -static void display(FILE *f, Node *n) { - /* Print standard HTML header */ - - Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version()); - Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version()); - Printf(f, "[ <a href=\"exit.html\">Exit</a> ]"); - Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top); - if (n != tree_top) { - Printf(f, " [ <a href=\"index.html?node=%p\">Up</a> ]", parentNode(n)); - } - Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]"); - Printf(f, "<br><hr><p>\n"); - - out = f; - - browse->emit_one(n); - - /* Print standard footer */ - Printf(f, "<br><hr></BODY></HTML>\n"); - -} - -void node_handler(FILE *f) { - Node *n = 0; - if (!swill_getargs("p(node)", &n)) { - n = tree_top; - } - view_top = n; - display(f, n); -} - - -/* ---------------------------------------------------------------------- - * hide_handler() - Hide a node - * ---------------------------------------------------------------------- */ - -void hide_handler(FILE *f) { - Node *n = 0; - if (!swill_getargs("p(hn)", &n)) { - n = 0; - } - if (n) { - Delmeta(n, "visible"); - } - node_handler(f); -} - -void show_handler(FILE *f) { - Node *n = 0; - if (!swill_getargs("p(hn)", &n)) { - n = 0; - } - if (n) { - Setmeta(n, "visible", "1"); - } - node_handler(f); -} - -void raw_data(FILE *out, Node *obj) { - if (!obj) - return; - if (DohIsMapping(obj)) { - String *k; - Iterator ki; - String *os = NewString(""); - Printf(os, "Hash {\n"); - ki = First(obj); - while (ki.key) { - k = ki.key; - DOH *o; - const char *trunc = ""; - if (DohIsString(Getattr(obj, k))) { - o = Str(Getattr(obj, k)); - if (Len(o) > 70) { - trunc = "..."; - } - Replaceall(o, "<", "<"); - Printf(os, " <a href=\"data.html?n=%p\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc); - Delete(o); - } else { - Printf(os, " <a href=\"data.html?n=%p\">?</a> %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k)); - } - ki = Next(ki); - } - Printf(os, "}\n"); - Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os)); - Delete(os); - } else if (DohIsString(obj)) { - String *o = Str(obj); - Replaceall(o, "<", "<"); - Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(o)); - Delete(o); - } else if (DohIsSequence(obj)) { - int i; - String *os = NewString(""); - Printf(os, "List [\n"); - for (i = 0; i < Len(obj); i++) { - DOH *o = Getitem(obj, i); - const char *trunc = ""; - if (DohIsString(o)) { - String *s = Str(o); - if (Len(s) > 70) { - trunc = "..."; - } - Replaceall(o, "<", "<"); - Printf(os, " <a href=\"data.html?n=%p\">?</a> [%d] - \"%(escape)-0.70s%s\"\n", o, i, s, trunc); - Delete(s); - } else { - Printf(os, " <a href=\"data.html?n=%p\">?</a> [%d] - %p\n", o, i, o); - } - } - Printf(os, "\n]\n"); - Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os)); - Delete(os); - } -} - -void data_handler(FILE *f) { - DOH *n = 0; - if (!swill_getargs("p(n)", &n)) { - n = 0; - } - Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version()); - Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version()); - Printf(f, "[ <a href=\"exit.html\">Exit</a> ]"); - Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top); - Printf(f, "<br><hr><p>\n"); - if (n) { - raw_data(f, n); - } - /* Print standard footer */ - Printf(f, "<br><hr></BODY></HTML>\n"); -} - -void symbol_handler(FILE *f) { - Symtab *sym; - char *name = 0; - - Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version()); - Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version()); - Printf(f, "[ <a href=\"exit.html\">Exit</a> ]"); - Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top); - Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]"); - Printf(f, "<br><hr><p>\n"); - - if (!swill_getargs("p(sym)|s(name)", &sym, &name)) { - sym = Swig_symbol_getscope(""); - name = 0; - } - if (!sym) { - Printf(f, "No symbol table specified!\n"); - return; - } - { - String *q = Swig_symbol_qualifiedscopename(sym); - if (!Len(q)) { - Printf(f, "<b>Symbol table: :: (global)</b><br>\n"); - } else { - Printf(f, "<b>Symbol table: %s</b><br>\n", q); - } - Delete(q); - } - - fprintf(f, "<p><form action=\"symbol.html\" method=GET>\n"); - fprintf(f, "Symbol lookup: <input type=text name=name size=40></input><br>\n"); - fprintf(f, "<input type=hidden name=sym value=\"%p\">\n", sym); - fprintf(f, "Submit : <input type=submit></input>\n"); - fprintf(f, "</form>"); - - if (name) { - Node *n = Swig_symbol_clookup(name, sym); - Printf(f, "Symbol '%s':\n", name); - Printf(f, "<blockquote>\n"); - if (!n) { - Printf(f, "Not defined!\n"); - } else { - raw_data(f, n); - } - Printf(f, "</blockquote>\n"); - } - - Printf(f, "<p><b>Nested scopes</b><br>\n"); - Printf(f, "<blockquote><pre>\n"); - { - Hash *h; - h = firstChild(sym); - while (h) { - Printf(f, "<a href=\"symbol.html?sym=%p\">%s</a>\n", h, Getattr(h, "name")); - h = nextSibling(h); - } - } - Printf(f, "</pre></blockquote>\n"); - - Printf(f, "<p><b>Symbol table contents</b></br>\n"); - raw_data(f, Getattr(sym, "symtab")); - Printf(f, "<br><hr></BODY></HTML>\n"); - -} -#endif - -void Swig_browser(Node *top, int port) { -#ifdef SWIG_SWILL - int sport; - browser_exit = 0; - - /* Initialize the server */ - sport = swill_init(port); - if (sport < 0) { - Printf(stderr, "Couldn't open socket on port %d. Sorry.\n", port); - return; - } - browse = new Browser(); - Setmeta(top, "visible", "1"); - tree_top = top; - - Printf(stderr, "SWIG: Tree browser listening on port %d\n", sport); - - swill_handle("exit.html", exit_handler, 0); - swill_handle("index.html", node_handler, 0); - swill_handle("hide.html", hide_handler, 0); - swill_handle("show.html", show_handler, 0); - swill_handle("data.html", data_handler, 0); - swill_handle("symbol.html", symbol_handler, 0); - swill_netscape("index.html"); - - while (!browser_exit) { - swill_serve(); - } - Printf(stderr, "Browser terminated.\n"); - swill_close(); - delete browse; - return; -#else - (void) top; - (void) port; -#endif -} diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx deleted file mode 100644 index 6333fa153..000000000 --- a/Source/Modules/cffi.cxx +++ /dev/null @@ -1,1184 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. - * - * cffi.cxx - * - * cffi language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <ctype.h> - -//#define CFFI_DEBUG -//#define CFFI_WRAP_DEBUG - -static const char *usage = "\ -CFFI Options (available with -cffi)\n\ - -generate-typedef - Use defctype to generate shortcuts according to the\n\ - typedefs in the input.\n\ - -[no]cwrap - Turn on or turn off generation of an intermediate C\n\ - file when creating a C interface. By default this is\n\ - only done for C++ code.\n\ - -[no]swig-lisp - Turn on or off generation of code for helper lisp\n\ - macro, functions, etc. which SWIG uses while\n\ - generating wrappers. These macros, functions may still\n\ - be used by generated wrapper code.\n\ -"; - -class CFFI:public Language { -public: - String *f_cl; - String *f_clhead; - String *f_clwrap; - bool CWrap; // generate wrapper file for C code? - File *f_begin; - File *f_runtime; - File *f_cxx_header; - File *f_cxx_wrapper; - File *f_clos; - - 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: - static void checkConstraints(ParmList *parms, Wrapper *f); - static void argout(ParmList *parms, Wrapper *f); - static String *freearg(ParmList *parms); - static void cleanupFunction(Node *n, Wrapper *f, ParmList *parms); - - void emit_defun(Node *n, String *name); - void emit_defmethod(Node *n); - void emit_initialize_instance(Node *n); - void emit_getter(Node *n); - void emit_setter(Node *n); - void emit_class(Node *n); - void emit_struct_union(Node *n, bool un); - void emit_export(Node *n, String *name); - void emit_inline(Node *n, String *name); - String *lispy_name(char *name); - String *lispify_name(Node *n, String *ty, const char *flag, bool kw = false); - String *convert_literal(String *num_param, String *type, bool try_to_split = true); - String *infix_to_prefix(String *val, char split_op, const String *op, String *type); - String *strip_parens(String *string); - String *trim(String *string); - int generate_typedef_flag; - bool no_swig_lisp; -}; - -void CFFI::main(int argc, char *argv[]) { - int i; - - Preprocessor_define("SWIGCFFI 1", 0); - SWIG_library_directory("cffi"); - SWIG_config_file("cffi.swg"); - generate_typedef_flag = 0; - no_swig_lisp = false; - CWrap = false; - for (i = 1; i < argc; i++) { - if (!Strcmp(argv[i], "-help")) { - Printf(stdout, "%s\n", usage); - } else if (!strcmp(argv[i], "-cwrap")) { - CWrap = true; - Swig_mark_arg(i); - } else if ((Strcmp(argv[i], "-generate-typedef") == 0)) { - generate_typedef_flag = 1; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-nocwrap")) { - CWrap = false; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-swig-lisp")) { - no_swig_lisp = false; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-noswig-lisp")) { - no_swig_lisp = true; - Swig_mark_arg(i); - } - - } - f_clhead = NewString(""); - f_clwrap = NewString(""); - f_cl = NewString(""); - - allow_overloading(); -} - -int CFFI::top(Node *n) { - File *f_null = NewString(""); - module = Getattr(n, "name"); - - String *cxx_filename = Getattr(n, "outfile"); - String *lisp_filename = NewString(""); - - Printf(lisp_filename, "%s%s.lisp", SWIG_output_directory(), module); - - File *f_lisp = NewFile(lisp_filename, "w", SWIG_output_files()); - if (!f_lisp) { - FileErrorDisplay(lisp_filename); - SWIG_exit(EXIT_FAILURE); - } - - if (CPlusPlus || CWrap) { - f_begin = NewFile(cxx_filename, "w", SWIG_output_files()); - if (!f_begin) { - Delete(f_lisp); - Printf(stderr, "Unable to open %s for writing\n", cxx_filename); - SWIG_exit(EXIT_FAILURE); - } - - String *clos_filename = NewString(""); - Printf(clos_filename, "%s%s-clos.lisp", SWIG_output_directory(), module); - f_clos = NewFile(clos_filename, "w", SWIG_output_files()); - if (!f_clos) { - Delete(f_lisp); - Printf(stderr, "Unable to open %s for writing\n", cxx_filename); - SWIG_exit(EXIT_FAILURE); - } - } else { - f_begin = NewString(""); - f_clos = NewString(""); - } - - f_runtime = NewString(""); - f_cxx_header = f_runtime; - f_cxx_wrapper = NewString(""); - - Swig_register_filebyname("header", f_cxx_header); - Swig_register_filebyname("wrapper", f_cxx_wrapper); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("lisphead", f_clhead); - if (!no_swig_lisp) - Swig_register_filebyname("swiglisp", f_cl); - else - Swig_register_filebyname("swiglisp", f_null); - - Swig_banner(f_begin); - - Printf(f_runtime, "\n\n#ifndef SWIGCFFI\n#define SWIGCFFI\n#endif\n\n"); - - Swig_banner_target_lang(f_lisp, ";;;"); - - Language::top(n); - Printf(f_lisp, "%s\n", f_clhead); - Printf(f_lisp, "%s\n", f_cl); - Printf(f_lisp, "%s\n", f_clwrap); - - Delete(f_lisp); - Delete(f_cl); - Delete(f_clhead); - Delete(f_clwrap); - Dump(f_runtime, f_begin); - Delete(f_runtime); - Delete(f_begin); - Delete(f_cxx_wrapper); - Delete(f_null); - - 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) { - emit_class(n); - 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", Getattr(n, "kind"), Getattr(n, "sym:name")); -#endif - Setattr(n, "cffi:constructorfunction", "1"); - // 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); -} - -void CFFI::emit_defmethod(Node *n) { - String *args_placeholder = NewStringf(""); - String *args_call = NewStringf(""); - - ParmList *pl = Getattr(n, "parms"); - int argnum = 0; - Node *parent = getCurrentClass(); - bool first = 0; - - for (Parm *p = pl; p; p = nextSibling(p), argnum++) { - String *argname = Getattr(p, "name"); - String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0); - - int tempargname = 0; - - if(!first) - first = true; - else - Printf(args_placeholder, " "); - - if (!argname) { - argname = NewStringf("arg%d", argnum); - tempargname = 1; - } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) { - argname = NewStringf("t-arg%d", argnum); - tempargname = 1; - } - if (Len(ffitype) > 0) - Printf(args_placeholder, "(%s %s)", argname, ffitype); - else - Printf(args_placeholder, "%s", argname); - - if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0) - Printf(args_call, " (ff-pointer %s)", argname); - else - Printf(args_call, " %s", argname); - - Delete(ffitype); - - if (tempargname) - Delete(argname); - } - - String *method_name = Getattr(n, "name"); - int x = Replace(method_name, "operator ", "", DOH_REPLACE_FIRST); // - - if (x == 1) - Printf(f_clos, "(cl:shadow \"%s\")\n", method_name); - - Printf(f_clos, "(cl:defmethod %s (%s)\n (%s%s))\n\n", - lispify_name(n, lispy_name(Char(method_name)), "'method"), args_placeholder, - lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call); - -} - -void CFFI::emit_initialize_instance(Node *n) { - String *args_placeholder = NewStringf(""); - String *args_call = NewStringf(""); - - ParmList *pl = Getattr(n, "parms"); - int argnum = 0; - Node *parent = getCurrentClass(); - - for (Parm *p = pl; p; p = nextSibling(p), argnum++) { - String *argname = Getattr(p, "name"); - String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0); - - int tempargname = 0; - if (!argname) { - argname = NewStringf("arg%d", argnum); - tempargname = 1; - } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) { - argname = NewStringf("t-arg%d", argnum); - tempargname = 1; - } - if (Len(ffitype) > 0) - Printf(args_placeholder, " (%s %s)", argname, ffitype); - else - Printf(args_placeholder, " %s", argname); - - if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0) - Printf(args_call, " (ff-pointer %s)", argname); - else - Printf(args_call, " %s", argname); - - Delete(ffitype); - - if (tempargname) - Delete(argname); - } - - Printf(f_clos, "(cl:defmethod initialize-instance :after ((obj %s) &key%s)\n (setf (slot-value obj 'ff-pointer) (%s%s)))\n\n", - lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), args_placeholder, - lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call); - -} - -void CFFI::emit_setter(Node *n) { - Node *parent = getCurrentClass(); - Printf(f_clos, "(cl:defmethod (cl:setf %s) (arg0 (obj %s))\n (%s (ff-pointer obj) arg0))\n\n", - lispify_name(n, Getattr(n, "name"), "'method"), - lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function")); -} - - -void CFFI::emit_getter(Node *n) { - Node *parent = getCurrentClass(); - Printf(f_clos, "(cl:defmethod %s ((obj %s))\n (%s (ff-pointer obj)))\n\n", - lispify_name(n, Getattr(n, "name"), "'method"), - lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function")); -} - -int CFFI::memberfunctionHandler(Node *n) { - // Let SWIG generate a global forwarding function. - Setattr(n, "cffi:memberfunction", "1"); - return Language::memberfunctionHandler(n); -} - -int CFFI::membervariableHandler(Node *n) { - // Let SWIG generate a get/set function pair. - Setattr(n, "cffi:membervariable", "1"); - return Language::membervariableHandler(n); -} - - -void CFFI::checkConstraints(ParmList *parms, Wrapper *f) { - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:check"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:check:next"); - } - } -} - -void CFFI::argout(ParmList *parms, Wrapper *f) { - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:argout"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$result", Swig_cresult_name()); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:argout:next"); - } - } -} - -String *CFFI::freearg(ParmList *parms) { - String *ret = NewString(""); - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:freearg"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(ret, tm, "\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:freearg:next"); - } - } - return ret; -} - -void CFFI::cleanupFunction(Node *n, Wrapper *f, ParmList *parms) { - String *cleanup = freearg(parms); - Printv(f->code, cleanup, NULL); - - if (GetFlag(n, "feature:new")) { - String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); - if (tm) { - Printv(f->code, tm, "\n", NULL); - Delete(tm); - } - } - - Replaceall(f->code, "$cleanup", cleanup); - Delete(cleanup); - - Replaceall(f->code, "$symname", Getattr(n, "sym:name")); -} - -int CFFI::functionWrapper(Node *n) { - - ParmList *parms = Getattr(n, "parms"); - String *iname = Getattr(n, "sym:name"); - Wrapper *f = NewWrapper(); - - String *raw_return_type = Swig_typemap_lookup("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(f, "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)) { - DelWrapper(f); - return SWIG_ERROR; - } - } - - String *wname = Swig_name_wrapper(iname); - if (overname) { - Append(wname, overname); - } - Setattr(n, "wrap:name", wname); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(parms, f); - - // Attach the standard typemaps - Swig_typemap_attach_parms("ctype", parms, f); - emit_attach_parmmaps(parms, f); - - 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(f->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(f->def, "EXPORT %s {", signature); - - checkConstraints(parms, f); - - Printf(f->code, " try {\n"); - - String *actioncode = emit_action(n); - - String *result_convert = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode); - if (result_convert) { - Replaceall(result_convert, "$result", "lresult"); - Printf(f->code, "%s\n", result_convert); - } - Delete(result_convert); - - argout(parms, f); - - cleanupFunction(n, f, parms); - - /* See if there is any return cleanup code */ - String *tm = 0; - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - if (!is_void_return) { - Printf(f->code, " return lresult;\n"); - } - - emit_return_variable(n, Getattr(n, "type"), f); - - Printf(f->code, " } catch (...) {\n"); - if (!is_void_return) - Printf(f->code, " return (%s)0;\n", raw_return_type); - Printf(f->code, " }\n"); - Printf(f->code, "}\n"); - - if (CPlusPlus) - Wrapper_print(f, f_runtime); - - if (CPlusPlus) { - emit_defun(n, wname); - if (Getattr(n, "cffi:memberfunction")) - emit_defmethod(n); - else if (Getattr(n, "cffi:membervariable")) { - if (Getattr(n, "memberget")) - emit_getter(n); - else if (Getattr(n, "memberset")) - emit_setter(n); - } - else if (Getattr(n, "cffi:constructorfunction")) { - emit_initialize_instance(n); - } - } 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); - // } - // } - - Delete(wname); - DelWrapper(f); - - return SWIG_OK; -} - - -void CFFI::emit_defun(Node *n, String *name) { - String *func_name = Getattr(n, "sym:name"); - - ParmList *pl = Getattr(n, "parms"); - - int argnum = 0; - - func_name = lispify_name(n, func_name, "'function"); - - emit_inline(n, func_name); - - Printf(f_cl, "\n(cffi:defcfun (\"%s\" %s)", name, func_name); - String *ffitype = Swig_typemap_lookup("cout", n, ":pointer", 0); - - Printf(f_cl, " %s", ffitype); - Delete(ffitype); - - for (Parm *p = pl; p; p = nextSibling(p), argnum++) { - - if (SwigType_isvarargs(Getattr(p, "type"))) { - Printf(f_cl, "\n %s", NewString("&rest")); - continue; - } - - String *argname = Getattr(p, "name"); - - ffitype = Swig_typemap_lookup("cin", p, "", 0); - - int tempargname = 0; - if (!argname) { - - argname = NewStringf("arg%d", argnum); - tempargname = 1; - } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) { - argname = NewStringf("t_arg%d", argnum); - tempargname = 1; - } - - Printf(f_cl, "\n (%s %s)", argname, ffitype); - - Delete(ffitype); - - if (tempargname) - Delete(argname); - } - Printf(f_cl, ")\n"); /* finish arg list */ - - emit_export(n, func_name); -} - - -int CFFI::constantWrapper(Node *n) { - String *type = Getattr(n, "type"); - String *converted_value; - if (SwigType_type(type) == T_STRING) { - converted_value = NewString(Getattr(n, "rawval")); - } else { - converted_value = convert_literal(Getattr(n, "value"), type); - } - - String *name = lispify_name(n, Getattr(n, "sym:name"), "'constant"); - - if (Strcmp(name, "t") == 0 || Strcmp(name, "T") == 0) - name = NewStringf("t_var"); - - Printf(f_cl, "\n(cl:defconstant %s %s)\n", name, converted_value); - Delete(converted_value); - - emit_export(n, name); - return SWIG_OK; -} - -int CFFI::variableWrapper(Node *n) { - String *var_name = Getattr(n, "sym:name"); - String *lisp_type = Swig_typemap_lookup("cin", n, "", 0); - String *lisp_name = lispify_name(n, var_name, "'variable"); - - if (Strcmp(lisp_name, "t") == 0 || Strcmp(lisp_name, "T") == 0) - lisp_name = NewStringf("t_var"); - - Printf(f_cl, "\n(cffi:defcvar (\"%s\" %s)\n %s)\n", var_name, lisp_name, lisp_type); - - Delete(lisp_type); - - emit_export(n, lisp_name); - return SWIG_OK; -} - -int CFFI::typedefHandler(Node *n) { - if (generate_typedef_flag && strncmp(Char(Getattr(n, "type")), "enum", 4)) { - String *lisp_name = lispify_name(n, Getattr(n, "name"), "'typename"); - Printf(f_cl, "\n(cffi:defctype %s %s)\n", lisp_name, Swig_typemap_lookup("cin", n, "", 0)); - emit_export(n, lisp_name); - } - return Language::typedefHandler(n); -} - -int CFFI::enumDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *name = Getattr(n, "sym:name"); - bool slot_name_keywords; - String *lisp_name = 0; - if (name && Len(name) != 0) { - lisp_name = lispify_name(n, name, "'enumname"); - if (GetFlag(n, "feature:bitfield")) { - Printf(f_cl, "\n(cffi:defbitfield %s", lisp_name); - } else { - Printf(f_cl, "\n(cffi:defcenum %s", lisp_name); - } - slot_name_keywords = true; - - //Registering the enum name to the cin and cout typemaps - Parm *pattern = NewParm(name, NULL, n); - Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); - Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); - Delete(pattern); - //Registering with the kind, i.e., enum - pattern = NewParm(NewStringf("enum %s", name), NULL, n); - Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); - Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); - Delete(pattern); - - } else { - Printf(f_cl, "\n(defanonenum %s", name); - slot_name_keywords = false; - } - - for (Node *c = firstChild(n); c; c = nextSibling(c)) { - - String *slot_name = lispify_name(c, Getattr(c, "name"), "'enumvalue", slot_name_keywords); - String *value = Getattr(c, "enumvalue"); - - if (!value || GetFlag(n, "feature:bitfield:ignore_values")) - Printf(f_cl, "\n\t%s", slot_name); - else { - String *type = Getattr(c, "type"); - String *converted_value = convert_literal(value, type); - Printf(f_cl, "\n\t(%s #.%s)", slot_name, converted_value); - Delete(converted_value); - } - Delete(value); - } - - Printf(f_cl, ")\n"); - - // No need to export keywords - if (lisp_name && Len(lisp_name) != 0) { - emit_export(n, lisp_name); - } else { - for (Node *c = firstChild(n); c; c = nextSibling(c)) - emit_export(c, lispify_name(c, Getattr(c, "name"), "'enumvalue")); - } - - return SWIG_OK; -} -void CFFI::emit_class(Node *n) { - -#ifdef CFFI_WRAP_DEBUG - Printf(stderr, "emit_class: ENTER... '%s'(%p)\n", Getattr(n, "sym:name"), n); -#endif - - String *name = Getattr(n, "sym:name"); - String *lisp_name = lispify_name(n, lispy_name(Char(name)), "'classname"); - - String *bases = Getattr(n, "bases"); - String *supers = NewString("("); - if (bases) { - int first = 1; - for (Iterator i = First(bases); i.item; i = Next(i)) { - if (!first) - Printf(supers, " "); - String *s = Getattr(i.item, "name"); - Printf(supers, "%s", lispify_name(i.item, lispy_name(Char(s)), "'classname")); - } - } else { - // Printf(supers,"ff:foreign-pointer"); - } - - Printf(supers, ")"); - Printf(f_clos, "\n(cl:defclass %s%s", lisp_name, supers); - Printf(f_clos, "\n ((ff-pointer :reader ff-pointer)))\n\n"); - - Parm *pattern = NewParm(Getattr(n, "name"), NULL, n); - - Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL); - SwigType_add_pointer(Getattr(pattern, "type")); - Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL); - SwigType_add_qualifier(Getattr(pattern, "type"), "const"); - Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL); - SwigType_del_pointer(Getattr(pattern, "type")); - SwigType_add_reference(Getattr(pattern, "type")); - Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL); - -#ifdef CFFI_WRAP_DEBUG - Printf(stderr, " pattern %s name %s .. ... %s .\n", pattern, lisp_name); -#endif - - Delete(pattern); - - // Walk children to generate type definition. - String *slotdefs = NewString(" "); - -#ifdef CFFI_WRAP_DEBUG - Printf(stderr, " walking children...\n"); -#endif - - Node *c; - for (c = firstChild(n); c; c = nextSibling(c)) { - String *storage_type = Getattr(c, "storage"); - if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) { - String *access = Getattr(c, "access"); - - // hack. why would decl have a value of "variableHandler" and now "0"? - String *childDecl = Getattr(c, "decl"); - // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view")); - if (!Strcmp(childDecl, "0")) - childDecl = NewString(""); - - SwigType *childType = NewStringf("%s%s", childDecl, - Getattr(c, "type")); - String *cname = (access && Strcmp(access, "public")) ? NewString("nil") : Copy(Getattr(c, "name")); - - if (!SwigType_isfunction(childType)) { - // Printf(slotdefs, ";;; member functions don't appear as slots.\n "); - // Printf(slotdefs, ";; "); - // String *ns = listify_namespace(Getattr(n, "cffi:package")); - String *ns = NewString(""); -#ifdef CFFI_WRAP_DEBUG - Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType); -#endif - Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, childType); //compose_foreign_type(childType) - Delete(ns); - if (access && Strcmp(access, "public")) - Printf(slotdefs, " ;; %s member", access); - - Printf(slotdefs, "\n "); - } - Delete(childType); - Delete(cname); - } - } - - - // String *ns_list = listify_namespace(Getattr(n,"cffi:namespace")); - // update_package_if_needed(n,f_clhead); - // Printf(f_clos, - // "(swig-def-foreign-class \"%s\"\n %s\n (:%s\n%s))\n\n", - // name, supers, kind, slotdefs); - - Delete(supers); - // Delete(ns_list); - - // Parm *pattern = NewParm(name, NULL, n); - // Swig_typemap_register("cin",pattern,lisp_name,NULL,NULL); - //Swig_typemap_register("cout",pattern,lisp_name,NULL,NULL); - //Delete(pattern); - -#ifdef CFFI_WRAP_DEBUG - Printf(stderr, "emit_class: EXIT\n"); -#endif -} - -// Includes structs -void CFFI::emit_struct_union(Node *n, bool un = false) { -#ifdef CFFI_DEBUG - Printf(stderr, "struct/union %s\n", Getattr(n, "name")); - Printf(stderr, "struct/union %s\n and %s", Getattr(n, "kind"), Getattr(n, "sym:name")); -#endif - - String *name = Getattr(n, "sym:name"); - String *kind = Getattr(n, "kind"); - - if (Strcmp(kind, "struct") != 0 && Strcmp(kind, "union") != 0) { - 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); - } - String *lisp_name = lispify_name(n, name, "'classname"); - - //Register the struct/union name to the cin and cout typemaps - - Parm *pattern = NewParm(name, NULL, n); - Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); - Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); - Delete(pattern); - //Registering with the kind, i.e., struct or union - pattern = NewParm(NewStringf("%s %s", kind, name), NULL, n); - Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); - Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); - Delete(pattern); - - if (un) { - Printf(f_cl, "\n(cffi:defcunion %s", lisp_name); - } else - Printf(f_cl, "\n(cffi:defcstruct %s", lisp_name); - - - for (Node *c = firstChild(n); c; c = nextSibling(c)) { -#ifdef CFFI_DEBUG - Printf(stderr, "struct/union %s\n", Getattr(c, "name")); - Printf(stderr, "struct/union %s and %s \n", Getattr(c, "kind"), Getattr(c, "sym:name")); -#endif - - if (Strcmp(nodeType(c), "cdecl")) { - //C declaration ignore - // 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); - } else { - SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"), Getattr(c, "type")); - - Node *node = NewHash(); - Setattr(node, "type", childType); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup("cin", node, "", 0); - - String *typespec = tm ? NewString(tm) : NewString(""); - - String *slot_name = lispify_name(c, Getattr(c, "sym:name"), "'slotname"); - if (slot_name && (Strcmp(slot_name, "t") == 0 || Strcmp(slot_name, "T") == 0)) - slot_name = NewStringf("t_var"); - - if (SwigType_isarray(childType) && SwigType_array_ndim(childType) == 1) { - String *dim = SwigType_array_getdim(childType, 0); - Printf(f_cl, "\n\t(%s %s :count %s)", slot_name, typespec, dim); - Delete(dim); - } else - Printf(f_cl, "\n\t(%s %s)", slot_name, typespec); - - Delete(node); - Delete(childType); - Delete(typespec); - } - } - - Printf(f_cl, ")\n"); - - emit_export(n, lisp_name); - for (Node *child = firstChild(n); child; child = nextSibling(child)) { - if (!Strcmp(nodeType(child), "cdecl")) { - emit_export(child, lispify_name(child, Getattr(child, "sym:name"), "'slotname")); - } - } - - /* Add this structure to the known lisp types */ - //Printf(stdout, "Adding %s foreign type\n", name); - // add_defined_foreign_type(name); - -} - -void CFFI::emit_export(Node *n, String *name) { - if (GetInt(n, "feature:export")) { - String* package = Getattr(n, "feature:export:package"); - Printf(f_cl, "\n(cl:export '%s%s%s)\n", name, package ? " " : "", - package ? package : ""); - } -} - -void CFFI::emit_inline(Node *n, String *name) { - if (GetInt(n, "feature:inline")) - Printf(f_cl, "\n(cl:declaim (cl:inline %s))\n", name); -} - -String *CFFI::lispify_name(Node *n, String *ty, const char *flag, bool kw) { - String *intern_func = Getattr(n, "feature:intern_function"); - if (intern_func) { - if (Strcmp(intern_func, "1") == 0) - intern_func = NewStringf("swig-lispify"); - return NewStringf("#.(%s \"%s\" %s%s)", intern_func, ty, flag, kw ? " :keyword" : ""); - } else if (kw) - return NewStringf(":%s", ty); - else - return ty; -} - -/* 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::trim(String *str) { - char *c = Char(str); - while (*c != '\0' && isspace((int) *c)) - ++c; - String *result = NewString(c); - Chop(result); - return result; -} - -String *CFFI::infix_to_prefix(String *val, char split_op, const String *op, String *type) { - List *ored = Split(val, split_op, -1); - - // some float hackery - //i don't understand it, if you do then please explain - // if ( ((split_op == '+') || (split_op == '-')) && Len(ored) == 2 && - // (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || - // SwigType_type(type) == T_LONGDOUBLE) ) { - // // check that we're not splitting a float - // String *possible_result = convert_literal(val, type, false); - // if (possible_result) return possible_result; - - // } - - // try parsing the split results. if any part fails, kick out. - bool part_failed = false; - if (Len(ored) > 1) { - String *result = NewStringf("(%s", op); - for (Iterator i = First(ored); i.item; i = Next(i)) { - String *converted = convert_literal(i.item, type); - if (converted) { - Printf(result, " %s", converted); - Delete(converted); - } else { - part_failed = true; - break; - } - } - Printf(result, ")"); - Delete(ored); - return part_failed ? 0 : result; - } else { - Delete(ored); - } - return 0; -} - -/* To be called by code generating the lisp interface - Will return a String containing the literal based on type. - Will return null if there are problems. - - try_to_split defaults to true (see stub above). -*/ -String *CFFI::convert_literal(String *literal, String *type, bool try_to_split) { - String *num_param = Copy(literal); - String *trimmed = trim(num_param); - String *num = strip_parens(trimmed), *res = 0; - Delete(trimmed); - char *s = Char(num); - - // very basic parsing of infix expressions. - if (try_to_split) { - if ((res = infix_to_prefix(num, '|', "cl:logior", type))) - return res; - if ((res = infix_to_prefix(num, '&', "cl:logand", type))) - return res; - if ((res = infix_to_prefix(num, '^', "cl:logxor", type))) - return res; - if ((res = infix_to_prefix(num, '*', "cl:*", type))) - return res; - if ((res = infix_to_prefix(num, '/', "cl:/", type))) - return res; - if ((res = infix_to_prefix(num, '+', "cl:+", type))) - return res; - if ((res = infix_to_prefix(num, '-', "cl:-", type))) - return res; - } - - if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) { - // Use CL syntax for float literals - - // careful. may be a float identifier or float constant. - char *num_start = Char(num); - char *num_end = num_start + strlen(num_start) - 1; - - bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-'); - - String *lisp_exp = 0; - if (is_literal) { - if (*num_end == 'f' || *num_end == 'F') { - lisp_exp = NewString("f"); - } else { - lisp_exp = NewString("d"); - } - - if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') { - *num_end = '\0'; - num_end--; - } - - int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp); - - if (!exponents) - Printf(num, "%s0", lisp_exp); - - if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) { - Delete(num); - num = 0; - } - } - return num; - } else if (SwigType_type(type) == T_CHAR) { - /* Use CL syntax for character literals */ - String* result = NewStringf("#\\%s", s); - Delete(num); - return result; - } else if (SwigType_type(type) == T_STRING) { - /* Use CL syntax for string literals */ - String* result = NewStringf("\"%s\"", num_param); - Delete(num); - return result; - } else if (SwigType_type(type) == T_INT || SwigType_type(type) == T_UINT) { - // Printf(stderr, "Is a T_INT or T_UINT %s, before replaceall\n", s); - const char *num_start = Char(num); - bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-'); - if (is_literal) { - Replaceall(num, "u", ""); - Replaceall(num, "U", ""); - Replaceall(num, "l", ""); - Replaceall(num, "L", ""); - } - - int i, j; - if (sscanf(s, "%d >> %d", &i, &j) == 2) { - String* result = NewStringf("(cl:ash %d -%d)", i, j); - Delete(num); - return result; - } else if (sscanf(s, "%d << %d", &i, &j) == 2) { - String* result = NewStringf("(cl:ash %d %d)", i, j); - Delete(num); - return result; - } - } - - if (Len(num) >= 2 && s[0] == '0') { /* octal or hex */ - if (s[1] == 'x'){ - Replace(num,"0","#",DOH_REPLACE_FIRST); - } - else{ - Replace(num,"0","#o",DOH_REPLACE_FIRST); - } - } - return num; -} - -//less flexible as it does the conversion in C, the lispify name does the conversion in lisp -String *CFFI::lispy_name(char *name) { - bool helper = false; - String *new_name = NewString(""); - for (unsigned int i = 0; i < strlen(name); i++) { - if (name[i] == '_' || name[i] == '-') { - Printf(new_name, "%c", '-'); - helper = false; - } else if (name[i] >= 'A' && name[i] <= 'Z') { - if (helper) - Printf(new_name, "%c", '-'); - Printf(new_name, "%c", ('a' + (name[i] - 'A'))); - helper = false; - } else { - helper = true; - Printf(new_name, "%c", name[i]); - } - } - return new_name; -} - -extern "C" Language *swig_cffi(void) { - return new CFFI(); -} diff --git a/Source/Modules/contract.cxx b/Source/Modules/contract.cxx index 7e0eaf9e0..dfc85ebe7 100644 --- a/Source/Modules/contract.cxx +++ b/Source/Modules/contract.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * contract.cxx * diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index edb79e13e..3cebb346c 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * csharp.cxx * @@ -12,8 +12,8 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" -#include <limits.h> // for INT_MAX #include "cparse.h" +#include <limits.h> // for INT_MAX #include <ctype.h> /* Hash type used for upcalls from C/C++ */ @@ -316,24 +316,24 @@ public: if (!outfile) { Printf(stderr, "Unable to determine outfile\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (directorsEnabled()) { if (!outfile_h) { Printf(stderr, "Unable to determine outfile_h\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -670,7 +670,7 @@ public: f_single_out = NewFile(filen, "w", SWIG_output_files()); if (!f_single_out) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -684,7 +684,7 @@ public: File *f = NewFile(filen, "w", SWIG_output_files()); if (!f) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -1699,10 +1699,9 @@ public: * addInterfaceNameAndUpcasts() * ----------------------------------------------------------------------------- */ - void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) { - List *keys = Keys(base_list); - for (Iterator it = First(keys); it.item; it = Next(it)) { - Node *base = Getattr(base_list, it.item); + void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) { + for (Iterator it = First(base_list); it.item; it = Next(it)) { + Node *base = it.item; SwigType *c_baseclassname = Getattr(base, "name"); String *interface_name = Getattr(base, "interface:name"); if (Len(interface_list)) @@ -1729,7 +1728,6 @@ public: Delete(cptr_method_name); Delete(interface_code); } - Delete(keys); } /* ----------------------------------------------------------------------------- @@ -1806,7 +1804,7 @@ public: if (baselist) { Iterator base = First(baselist); while (base.item) { - if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) { + if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) { SwigType *baseclassname = Getattr(base.item, "name"); if (!c_baseclassname) { String *name = getProxyName(baseclassname); @@ -1825,7 +1823,7 @@ public: } } } - Hash *interface_bases = Getattr(n, "interface:bases"); + List *interface_bases = Getattr(n, "interface:bases"); if (interface_bases) addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname); @@ -1964,9 +1962,32 @@ public: // Only emit if there is at least one director method Printf(proxy_class_code, "\n"); Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n"); - Printf(proxy_class_code, - " global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n"); - Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name); + Printf(proxy_class_code, " global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n"); + Printf(proxy_class_code, " global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n"); + Printf(proxy_class_code, " foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n"); + Printf(proxy_class_code, " if (methodInfo.DeclaringType == null)\n"); + Printf(proxy_class_code, " continue;\n\n"); + Printf(proxy_class_code, " if (methodInfo.Name != methodName)\n"); + Printf(proxy_class_code, " continue;\n\n"); + Printf(proxy_class_code, " var parameters = methodInfo.GetParameters();\n"); + Printf(proxy_class_code, " if (parameters.Length != methodTypes.Length)\n"); + Printf(proxy_class_code, " continue;\n\n"); + Printf(proxy_class_code, " bool parametersMatch = true;\n"); + Printf(proxy_class_code, " for (var i = 0; i < parameters.Length; i++) {\n"); + Printf(proxy_class_code, " if (parameters[i].ParameterType != methodTypes[i]) {\n"); + Printf(proxy_class_code, " parametersMatch = false;\n"); + Printf(proxy_class_code, " break;\n"); + Printf(proxy_class_code, " }\n"); + Printf(proxy_class_code, " }\n\n"); + Printf(proxy_class_code, " if (!parametersMatch)\n"); + Printf(proxy_class_code, " continue;\n\n"); + Printf(proxy_class_code, " if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name); + Printf(proxy_class_code, " methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n"); + Printf(proxy_class_code, " return true;\n"); + Printf(proxy_class_code, " }\n"); + Printf(proxy_class_code, " }\n\n"); + Printf(proxy_class_code, " return false;\n"); + /* Could add this code to cover corner case where the GetMethod() returns a method which allows type * promotion, eg it will return foo(double), if looking for foo(int). if (hasDerivedMethod) { @@ -1986,7 +2007,7 @@ public: } } */ - Printf(proxy_class_code, " return hasDerivedMethod;\n"); + //Printf(proxy_class_code, " return hasDerivedMethod;\n"); Printf(proxy_class_code, " }\n"); } @@ -2045,7 +2066,7 @@ public: if (List *baselist = Getattr(n, "bases")) { String *bases = 0; for (Iterator base = First(baselist); base.item; base = Next(base)) { - if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface")) + if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface")) continue; // TODO: warn about skipped non-interface bases String *base_iname = Getattr(base.item, "interface:name"); if (!bases) @@ -2096,7 +2117,7 @@ public: if (proxy_flag) { proxy_class_name = NewString(Getattr(n, "sym:name")); - String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0; + String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0; if (Node *outer = Getattr(n, "nested:outer")) { String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { @@ -2122,12 +2143,12 @@ public: full_imclass_name = NewStringf("%s", imclass_name); if (Cmp(proxy_class_name, imclass_name) == 0) { Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (Cmp(proxy_class_name, module_class_name) == 0) { Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } else { if (namespce) { @@ -2152,7 +2173,7 @@ public: destructor_call = NewString(""); proxy_class_constants_code = NewString(""); - if (Getattr(n, "feature:interface")) { + if (GetFlag(n, "feature:interface")) { interface_class_code = NewString(""); String *output_directory = outputDirectory(nspace); f_interface = getOutputFile(output_directory, interface_name); @@ -2323,7 +2344,7 @@ public: String *pre_code = NewString(""); String *post_code = NewString(""); String *terminator_code = NewString(""); - bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 + bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable") && !static_flag && Getattr(n, "interface:owner") == 0; if (!proxy_flag) @@ -2553,8 +2574,8 @@ public: Replaceall(imcall, "$imfuncname", intermediary_function_name); String *excode = NewString(""); Node *directorNode = Getattr(n, "directorNode"); - if (directorNode) { - UpcallData *udata = Getattr(directorNode, "upcalldata"); + UpcallData *udata = directorNode ? Getattr(directorNode, "upcalldata") : 0; + if (udata) { String *methid = Getattr(udata, "class_methodidx"); if (!Cmp(return_type, "void")) @@ -2572,6 +2593,7 @@ public: } else { Replaceall(imcall, "$imfuncname", intermediary_function_name); } + Replaceall(tm, "$imfuncname", intermediary_function_name); Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0)); @@ -2615,6 +2637,7 @@ public: if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) { substituteClassname(cvariable_type, tm); Replaceall(tm, "$csinput", "value"); + Replaceall(tm, "$imfuncname", intermediary_function_name); Replaceall(tm, "$imcall", imcall); excodeSubstitute(n, tm, "csvarin", variable_parm); Printf(proxy_class_code, "%s", tm); @@ -2629,6 +2652,7 @@ public: else Replaceall(tm, "$owner", "false"); substituteClassname(t, tm); + Replaceall(tm, "$imfuncname", intermediary_function_name); Replaceall(tm, "$imcall", imcall); excodeSubstitute(n, tm, "csvarout", n); Printf(proxy_class_code, "%s", tm); @@ -3141,6 +3165,7 @@ public: else Replaceall(tm, "$owner", "false"); substituteClassname(t, tm); + Replaceall(tm, "$imfuncname", overloaded_name); Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0)); @@ -3179,6 +3204,7 @@ public: if ((tm = Getattr(p, "tmap:csvarin"))) { substituteClassname(pt, tm); Replaceall(tm, "$csinput", "value"); + Replaceall(tm, "$imfuncname", overloaded_name); Replaceall(tm, "$imcall", imcall); excodeSubstitute(n, tm, "csvarin", p); Printf(module_class_code, "%s", tm); @@ -3193,6 +3219,7 @@ public: else Replaceall(tm, "$owner", "false"); substituteClassname(t, tm); + Replaceall(tm, "$imfuncname", overloaded_name); Replaceall(tm, "$imcall", imcall); excodeSubstitute(n, tm, "csvarout", n); Printf(module_class_code, "%s", tm); @@ -3660,7 +3687,7 @@ public: if (newdir_error) { Printf(stderr, "%s\n", newdir_error); Delete(newdir_error); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); Delete(nspace_subdirectory); diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index b7283eac2..4704d8d54 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * d.cxx * @@ -378,24 +378,24 @@ public: if (!outfile) { Printf(stderr, "Unable to determine outfile\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (directorsEnabled()) { if (!outfile_h) { Printf(stderr, "Unable to determine outfile_h\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -518,7 +518,7 @@ public: File *im_d_file = NewFile(filen, "w", SWIG_output_files()); if (!im_d_file) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -549,7 +549,7 @@ public: File *proxy_d_file = NewFile(filen, "w", SWIG_output_files()); if (!proxy_d_file) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -583,7 +583,7 @@ public: File *file = NewFile(filename, "w", SWIG_output_files()); if (!file) { FileErrorDisplay(filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(filename); @@ -863,7 +863,7 @@ public: File *class_file = NewFile(filename, "w", SWIG_output_files()); if (!class_file) { FileErrorDisplay(filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filename)); Delete(filename); @@ -1335,7 +1335,7 @@ public: Delete(output_directory); if (!class_file) { FileErrorDisplay(filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filename)); Delete(filename); @@ -2898,6 +2898,7 @@ private: } else { Replaceall(imcall, "$imfuncname", intermediary_function_name); } + Replaceall(tm, "$imfuncname", intermediary_function_name); Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, @@ -3100,6 +3101,7 @@ private: else Replaceall(tm, "$owner", "false"); replaceClassname(tm, t); + Replaceall(tm, "$imfuncname", overloaded_name); Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, @@ -3400,7 +3402,7 @@ private: } else { Printv(upcasts_code, "SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name, - "(", baseclassname, " *objectRef) {\n", + "(", classname, " *objectRef) {\n", " return (", baseclassname, " *)objectRef;\n" "}\n", "\n", NIL); @@ -3434,7 +3436,7 @@ private: class_file = NewFile(filename, "w", SWIG_output_files()); if (!class_file) { FileErrorDisplay(filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filename)); Delete(filename); @@ -3756,7 +3758,7 @@ private: Swig_error(input_file, line_number, "Class name cannot be equal to intermediary D module name: %s\n", class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } String *nspace = getNSpace(); @@ -3769,7 +3771,7 @@ private: Swig_error(input_file, line_number, "Class name cannot be the same as the root package it is in: %s\n", class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(dotless_package); } else { @@ -3778,7 +3780,7 @@ private: Swig_error(input_file, line_number, "Class name cannot be the same as the outermost namespace it is in: %s\n", class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(outer); } @@ -3790,7 +3792,7 @@ private: Swig_error(input_file, line_number, "Class name cannot be the same as the innermost namespace it is in: %s\n", class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(inner); } else { @@ -3798,7 +3800,7 @@ private: Swig_error(input_file, line_number, "Class name cannot be equal to proxy D module name: %s\n", class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } } @@ -4498,7 +4500,7 @@ private: if (newdir_error) { Printf(stderr, "%s\n", newdir_error); Delete(newdir_error); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); Delete(nspace_subdirectory); diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx index 196974792..fbef70aa1 100644 --- a/Source/Modules/directors.cxx +++ b/Source/Modules/directors.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * directors.cxx * @@ -97,7 +97,6 @@ String *Swig_director_declaration(Node *n) { String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) { String *func; - int i = 0; int comma = 0; Parm *p = parms; SwigType *pt; @@ -115,7 +114,6 @@ String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) { pname = Getattr(p, "name"); Printf(func, "%s", pname); comma = 1; - i++; } p = nextSibling(p); } diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx index edfa57ccd..74adc5400 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * emit.cxx * diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index f97e7ee20..d39d396fc 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1,6 +1,10 @@ /* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * This file is part of SWIG, which is licensed as a whole under version 3 + * (or any later version) of the GNU General Public License. Some additional + * terms also apply to certain portions of SWIG. The full details of the SWIG + * license and copyrights can be found in the LICENSE and COPYRIGHT files + * included with the SWIG source code as distributed by the SWIG developers + * and at https://www.swig.org/legal.html. * * go.cxx * @@ -244,7 +248,6 @@ private: virtual void main(int argc, char *argv[]) { SWIG_library_directory("go"); - bool display_help = false; bool saw_nocgo_flag = false; // Process command line options. @@ -329,7 +332,6 @@ private: Swig_arg_error(); } } else if (strcmp(argv[i], "-help") == 0) { - display_help = true; Printf(stdout, "%s\n", usage); } } @@ -337,7 +339,7 @@ private: if (saw_nocgo_flag) { Printf(stderr, "SWIG -go: -no-cgo option is no longer supported\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (gccgo_flag && !pkgpath_option && !prefix_option) { @@ -351,14 +353,6 @@ private: Preprocessor_define("SWIGGO_GCCGO 1", 0); } - // This test may be removed in the future, when we can assume that - // everybody has upgraded to Go 1.1. The code below is prepared - // for this test to simply be taken out. - if (intgo_type_size == 0 && !display_help) { - Printf(stderr, "SWIG -go: -intgosize option required but not specified\n"); - SWIG_exit(EXIT_FAILURE); - } - if (intgo_type_size == 32) { Preprocessor_define("SWIGGO_INTGO_SIZE 32", 0); } else if (intgo_type_size == 64) { @@ -377,7 +371,7 @@ private: /* --------------------------------------------------------------------- * top() * - * For 6g/8g, we are going to create the following files: + * For gc, we are going to create the following files: * * 1) A .c or .cxx file compiled with gcc. This file will contain * function wrappers. Each wrapper will take a pointer to a @@ -453,7 +447,7 @@ private: FILE *swig_input = Swig_open(swig_filename); if (swig_input == NULL) { FileErrorDisplay(swig_filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } String *swig_input_content = Swig_read_file(swig_input); siphash(&hash, Char(swig_input_content), Len(swig_input_content)); @@ -467,25 +461,25 @@ private: f_c_begin = NewFile(c_filename, "w", SWIG_output_files()); if (!f_c_begin) { FileErrorDisplay(c_filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (directorsEnabled()) { if (!c_filename_h) { Printf(stderr, "Unable to determine outfile_h\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_c_directors_h = NewFile(c_filename_h, "w", SWIG_output_files()); if (!f_c_directors_h) { FileErrorDisplay(c_filename_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } f_go_begin = NewFile(go_filename, "w", SWIG_output_files()); if (!f_go_begin) { FileErrorDisplay(go_filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_c_runtime = NewString(""); @@ -525,6 +519,8 @@ private: } Printf(f_c_runtime, "#define SWIGMODULE %s\n", module); + Printf(f_c_runtime, "#ifndef SWIGGO\n#define SWIGGO\n#endif\n\n"); + if (gccgo_flag) { Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix); } @@ -1262,9 +1258,15 @@ private: String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if ((i == 0 && info->is_destructor) || ((i > 0 || !info->receiver || info->base || info->is_constructor) && goTypeIsInterface(p, pt))) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); Setattr(p, "emit:goinput", ln); @@ -1457,7 +1459,7 @@ private: p = getParm(p); SwigType *pt = Copy(Getattr(p, "type")); - if (SwigType_isarray(pt)) { + if (SwigType_isarray(pt) && Getattr(p, "tmap:gotype") == NULL) { SwigType_del_array(pt); SwigType_add_pointer(pt); } @@ -2208,95 +2210,127 @@ private: } for (Node *ni = Getattr(base, "firstChild"); ni; ni = nextSibling(ni)) { - - if (GetFlag(ni, "feature:ignore")) { - continue; + int r = goBaseEntry(n, bases, local, ni); + if (r != SWIG_OK) { + return r; } + } - if (!is_public(ni)) { - continue; + List *baselist = Getattr(base, "bases"); + if (baselist && Len(baselist) > 0) { + for (Iterator b = First(baselist); b.item; b = Next(b)) { + List *nb = Copy(bases); + Append(nb, Getattr(b.item, "classtype")); + int r = addBase(n, b.item, nb, local); + Delete(nb); + if (r != SWIG_OK) { + return r; + } } + } - String *type = Getattr(ni, "nodeType"); - if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) { - continue; - } - String *storage = Getattr(ni, "storage"); - if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) { - continue; - } + return SWIG_OK; + } - String *mname = Getattr(ni, "sym:name"); - if (!mname) { - continue; - } + /* ------------------------------------------------------------ + * goBaseEntry() + * + * Implement one entry defined in a parent class for a child class. + * n is the child class. + * ------------------------------------------------------------ */ - String *lname = Getattr(ni, "name"); - if (Getattr(class_methods, lname)) { - continue; - } - if (Getattr(local, lname)) { - continue; - } - Setattr(local, lname, NewString("")); + int goBaseEntry(Node* n, List* bases, Hash *local, Node* entry) { + if (GetFlag(entry, "feature:ignore")) { + return SWIG_OK; + } - String *ty = NewString(Getattr(ni, "type")); - SwigType_push(ty, Getattr(ni, "decl")); - String *fullty = SwigType_typedef_resolve_all(ty); - bool is_function = SwigType_isfunction(fullty) ? true : false; - Delete(ty); - Delete(fullty); + if (!is_public(entry)) { + return SWIG_OK; + } + + String *type = Getattr(entry, "nodeType"); + if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) { + return SWIG_OK; + } - if (is_function) { - int r = goBaseMethod(n, bases, ni); + if (Strcmp(type, "extend") == 0) { + for (Node* extend = firstChild(entry); extend; extend = nextSibling(extend)) { + if (isStatic(extend)) { + // If we don't do this, the extend_default test case fails. + continue; + } + + int r = goBaseEntry(n, bases, local, extend); if (r != SWIG_OK) { return r; } + } + return SWIG_OK; + } - if (Getattr(ni, "sym:overloaded")) { - for (Node *on = Getattr(ni, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) { - r = goBaseMethod(n, bases, on); - if (r != SWIG_OK) { - return r; - } - } + String *storage = Getattr(entry, "storage"); + if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) { + return SWIG_OK; + } - String *receiver = class_receiver; - bool is_static = isStatic(ni); - if (is_static) { - receiver = NULL; - } - String *go_name = buildGoName(Getattr(ni, "sym:name"), is_static, false); - r = makeDispatchFunction(ni, go_name, receiver, is_static, NULL, false); - Delete(go_name); + String *mname = Getattr(entry, "sym:name"); + if (!mname) { + return SWIG_OK; + } + + String *lname = Getattr(entry, "name"); + if (Getattr(class_methods, lname)) { + return SWIG_OK; + } + if (Getattr(local, lname)) { + return SWIG_OK; + } + Setattr(local, lname, NewString("")); + + String *ty = NewString(Getattr(entry, "type")); + SwigType_push(ty, Getattr(entry, "decl")); + String *fullty = SwigType_typedef_resolve_all(ty); + bool is_function = SwigType_isfunction(fullty) ? true : false; + Delete(ty); + Delete(fullty); + + if (is_function) { + int r = goBaseMethod(n, bases, entry); + if (r != SWIG_OK) { + return r; + } + + if (Getattr(entry, "sym:overloaded")) { + for (Node *on = Getattr(entry, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) { + r = goBaseMethod(n, bases, on); if (r != SWIG_OK) { return r; } } - } else { - int r = goBaseVariable(n, bases, ni); - if (r != SWIG_OK) { - return r; - } - } - } - List *baselist = Getattr(base, "bases"); - if (baselist && Len(baselist) > 0) { - for (Iterator b = First(baselist); b.item; b = Next(b)) { - List *nb = Copy(bases); - Append(nb, Getattr(b.item, "classtype")); - int r = addBase(n, b.item, nb, local); - Delete(nb); + String *receiver = class_receiver; + bool is_static = isStatic(entry); + if (is_static) { + receiver = NULL; + } + String *go_name = buildGoName(Getattr(entry, "sym:name"), is_static, false); + r = makeDispatchFunction(entry, go_name, receiver, is_static, NULL, false); + Delete(go_name); if (r != SWIG_OK) { - return r; + return r; } } + } else { + int r = goBaseVariable(n, bases, entry); + if (r != SWIG_OK) { + return r; + } } return SWIG_OK; } + /* ------------------------------------------------------------ * goBaseMethod() * @@ -2351,7 +2385,13 @@ private: } } - int r = makeWrappers(method, go_name, overname, wname, bases, Getattr(method, "parms"), result, is_static); + // A method added by %extend in a base class may have void parms. + ParmList* parms = Getattr(method, "parms"); + if (parms != NULL && SwigType_type(Getattr(parms, "type")) == T_VOID) { + parms = NULL; + } + + int r = makeWrappers(method, go_name, overname, wname, bases, parms, result, is_static); Swig_restore(method); @@ -2506,7 +2546,7 @@ private: Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL); Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_type, " {\n", NULL); - Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(p.Swigcptr())\n", NULL); + Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(getSwigcptr(p))\n", NULL); Printv(f_go_wrappers, "}\n\n", NULL); Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n", NULL); @@ -2708,7 +2748,7 @@ private: Printv(f_go_wrappers, "}\n\n", NULL); Printv(f_go_wrappers, "func (p *", director_struct_name, ") Swigcptr() uintptr {\n", NULL); - Printv(f_go_wrappers, "\treturn p.", go_type_name, ".Swigcptr()\n", NULL); + Printv(f_go_wrappers, "\treturn getSwigcptr(p.", go_type_name, ")\n", NULL); Printv(f_go_wrappers, "}\n\n", NULL); Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs", go_name, "() {\n", NULL); @@ -2866,9 +2906,15 @@ private: String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); } else { @@ -3461,9 +3507,15 @@ private: // the goin typemap. String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); } else { @@ -3472,7 +3524,7 @@ private: goin = Copy(goin); Replaceall(goin, "$input", ln); Replaceall(goin, "$result", ivar); - Printv(f_go_wrappers, goin, NULL); + Printv(f_go_wrappers, goin, "\n", NULL); Delete(goin); } @@ -3534,114 +3586,11 @@ private: Printv(f_go_wrappers, "}\n\n", NULL); - // Define a method in the C++ director class that the C++ upcall - // function can call. This permits an upcall to a protected - // method. - if (!GetFlag(n, "abstract")) { - String *upcall_method_name = NewString("_swig_upcall_"); - Append(upcall_method_name, name); - if (overname) { - Append(upcall_method_name, overname); - } - SwigType *rtype = Getattr(n, "classDirectorMethods:type"); - String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0); - Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL); - Delete(upcall_decl); - - Printv(f_c_directors_h, " ", NULL); - if (SwigType_type(result) != T_VOID) { - Printv(f_c_directors_h, "return ", NULL); - } - - String *super_call = Swig_method_call(super, parms); - Printv(f_c_directors_h, super_call, ";\n", NULL); - Delete(super_call); - - Printv(f_c_directors_h, " }\n", NULL); - - // Define the C++ function that the Go function calls. - - SwigType *first_type = NULL; - Parm *first_parm = parms; - if (!is_static) { - first_type = NewString("SwigDirector_"); - Append(first_type, class_name); - SwigType_add_pointer(first_type); - first_parm = NewParm(first_type, "p", n); - set_nextSibling(first_parm, parms); - } - - Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL); - - Setattr(n, "wrap:name", upcall_wname); - - String *action = NewString(""); - if (SwigType_type(result) != T_VOID) { - Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL); - if (SwigType_isreference(result)) { - Printv(action, "&", NULL); - } - } - Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL); - - p = parms; - int i = 0; - while (p != NULL) { - if (SwigType_type(Getattr(p, "type")) != T_VOID) { - String *pname = Swig_cparm_name(NULL, i + 1); - if (i > 0) { - Printv(action, ", ", NULL); - } - - // A parameter whose type is a reference is converted into a - // pointer type by gcCTypeForGoValue. We are calling a - // function which expects a reference so we need to convert - // back. - if (SwigType_isreference(Getattr(p, "type"))) { - Printv(action, "*", NULL); - } - - Printv(action, pname, NULL); - Delete(pname); - i++; - } - p = nextSibling(p); - } - Printv(action, ");", NULL); - Setattr(n, "wrap:action", action); - - cgoWrapperInfo info; - - info.n = n; - info.go_name = go_name; - info.overname = overname; - info.wname = upcall_wname; - info.base = NULL; - info.parms = first_parm; - info.result = result; - info.is_static = is_static; - info.receiver = NULL; - info.is_constructor = false; - info.is_destructor = false; - - int r = cgoGccWrapper(&info); - if (r != SWIG_OK) { - return r; - } - - Delete(first_type); - if (first_parm != parms) { - Delete(first_parm); - } - - Swig_restore(n); - Delete(upcall_method_name); - // Define a function that uses the Go director type that other // methods in the Go type can call to get parent methods. - Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL); + Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(swig_p ", cn, NULL); p = parms; for (int i = 0; i < parm_count; ++i) { @@ -3694,7 +3643,7 @@ private: } } - Printv(call, "C.", upcall_wname, "(C.uintptr_t(p.(*", + Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.(*", director_struct_name, ").", go_type_name, ")", NULL); p = parms; @@ -3709,9 +3658,15 @@ private: String *goin = goGetattr(p, "tmap:goin"); if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL); + Printv(f_go_wrappers, "\t", ivar, " := ", NULL); + bool need_close = false; if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(f_go_wrappers, "getSwigcptr(", NULL); + need_close = true; + } + Printv(f_go_wrappers, ln, NULL); + if (need_close) { + Printv(f_go_wrappers, ")", NULL); } Printv(f_go_wrappers, "\n", NULL); } else { @@ -3720,7 +3675,7 @@ private: goin = Copy(goin); Replaceall(goin, "$input", ln); Replaceall(goin, "$result", ivar); - Printv(f_go_wrappers, goin, NULL); + Printv(f_go_wrappers, goin, "\n", NULL); Delete(goin); } @@ -3782,6 +3737,109 @@ private: if (wt) { Delete(wt); } + + // Define a method in the C++ director class that the C++ + // upcall function can call. This permits an upcall to a + // protected method. + + String *upcall_method_name = NewString("_swig_upcall_"); + Append(upcall_method_name, name); + if (overname) { + Append(upcall_method_name, overname); + } + SwigType *rtype = Getattr(n, "classDirectorMethods:type"); + String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0); + Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL); + Delete(upcall_decl); + + Printv(f_c_directors_h, " ", NULL); + if (SwigType_type(result) != T_VOID) { + Printv(f_c_directors_h, "return ", NULL); + } + + String *super_call = Swig_method_call(super, parms); + Printv(f_c_directors_h, super_call, ";\n", NULL); + Delete(super_call); + + Printv(f_c_directors_h, " }\n", NULL); + + // Define the C++ function that the Go function calls. + + SwigType *first_type = NULL; + Parm *first_parm = parms; + if (!is_static) { + first_type = NewString("SwigDirector_"); + Append(first_type, class_name); + SwigType_add_pointer(first_type); + first_parm = NewParm(first_type, "p", n); + set_nextSibling(first_parm, parms); + } + + Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL); + + Setattr(n, "wrap:name", upcall_wname); + + String *action = NewString(""); + if (SwigType_type(result) != T_VOID) { + Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL); + if (SwigType_isreference(result)) { + Printv(action, "&", NULL); + } + } + Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL); + + p = parms; + int i = 0; + while (p != NULL) { + if (SwigType_type(Getattr(p, "type")) != T_VOID) { + String *pname = Swig_cparm_name(NULL, i + 1); + if (i > 0) { + Printv(action, ", ", NULL); + } + + // A parameter whose type is a reference is converted into a + // pointer type by gcCTypeForGoValue. We are calling a + // function which expects a reference so we need to convert + // back. + if (SwigType_isreference(Getattr(p, "type"))) { + Printv(action, "*", NULL); + } + + Printv(action, pname, NULL); + Delete(pname); + i++; + } + p = nextSibling(p); + } + Printv(action, ");", NULL); + Setattr(n, "wrap:action", action); + + cgoWrapperInfo info; + + info.n = n; + info.go_name = go_name; + info.overname = overname; + info.wname = upcall_wname; + info.base = NULL; + info.parms = first_parm; + info.result = result; + info.is_static = is_static; + info.receiver = NULL; + info.is_constructor = false; + info.is_destructor = false; + + int r = cgoGccWrapper(&info); + if (r != SWIG_OK) { + return r; + } + + Delete(first_type); + if (first_parm != parms) { + Delete(first_parm); + } + + Swig_restore(n); + Delete(upcall_method_name); } // The Go function which invokes the method. This is called by @@ -3830,7 +3888,7 @@ private: if (SwigType_type(result) != T_VOID) { Printv(call, "swig_r = ", NULL); if (result_is_interface) { - Printv(call, result_wrapper, "(", NULL); + Printv(call, result_wrapper, "(getSwigcptr(", NULL); } } Printv(call, "swig_p.", go_with_over_name, "(", NULL); @@ -3890,7 +3948,7 @@ private: Printv(call, ")", NULL); if (result_is_interface) { - Printv(call, ".Swigcptr())", NULL); + Printv(call, "))", NULL); } Printv(call, "\n", NULL); @@ -5085,7 +5143,7 @@ private: } String *t = Copy(type); - if (SwigType_isarray(t)) { + if (SwigType_isarray(t) && Getattr(n, "tmap:gotype") == NULL) { SwigType_del_array(t); SwigType_add_pointer(t); } @@ -5284,7 +5342,7 @@ private: * gcCTypeForGoValue() * * Given a type, return the C/C++ type which will be used to catch - * the value in Go. This is the 6g/8g version. + * the value in Go. This is the gc version. * ---------------------------------------------------------------------- */ String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) { @@ -5293,7 +5351,19 @@ private: String *tail = NewString(""); SwigType *t = SwigType_typedef_resolve_all(type); - if (!SwigType_isreference(t)) { + bool is_const_ref = false; + if (SwigType_isreference(t)) { + SwigType* tt = Copy(t); + SwigType_del_reference(tt); + if (SwigType_isqualifier(tt)) { + String* q = SwigType_parm(tt); + if (Strcmp(q, "const") == 0) { + is_const_ref = true; + } + } + Delete(tt); + } + if (!is_const_ref) { while (Strncmp(gt, "*", 1) == 0) { Replace(gt, "*", "", DOH_REPLACE_FIRST); Printv(tail, "*", NULL); @@ -5437,17 +5507,6 @@ private: } /* ---------------------------------------------------------------------- - * gccgoCTypeForGoValue() - * - * Given a type, return the C/C++ type which will be used to catch - * the value in Go. This is the gccgo version. - * ---------------------------------------------------------------------- */ - - String *gccgoCTypeForGoValue(Node *n, SwigType *type, String *name) { - return gcCTypeForGoValue(n, type, name); - } - - /* ---------------------------------------------------------------------- * goTypeIsInterface * * Return whether this C++ type is represented as an interface type diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx index d7d3da8fc..874150e3a 100644 --- a/Source/Modules/guile.cxx +++ b/Source/Modules/guile.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * guile.cxx * @@ -12,7 +12,6 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" - #include <ctype.h> // Note string broken in half for compilers that can't handle long strings @@ -132,7 +131,7 @@ public: if (argv[i]) { if (strcmp(argv[i], "-help") == 0) { fputs(usage, stdout); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = NewString(argv[i + 1]); @@ -176,7 +175,7 @@ public: procdoc = NewFile(argv[i + 1], "w", SWIG_output_files()); if (!procdoc) { FileErrorDisplay(argv[i + 1]); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Swig_mark_arg(i); Swig_mark_arg(i + 1); @@ -255,7 +254,7 @@ public: if (goops) { if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) { Printf(stderr, "guile: GOOPS support requires passive or module linkage\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -298,7 +297,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); @@ -476,7 +475,8 @@ public: Printf(f_init, "}\n"); break; default: - abort(); // for now + fputs("Fatal internal error: Invalid Guile linkage setting.\n", stderr); + Exit(EXIT_FAILURE); } if (scmstub) { @@ -495,7 +495,7 @@ public: File *scmstubfile = NewFile(fname, "w", SWIG_output_files()); if (!scmstubfile) { FileErrorDisplay(fname); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(fname); @@ -526,7 +526,7 @@ public: File *goopsfile = NewFile(fname, "w", SWIG_output_files()); if (!goopsfile) { FileErrorDisplay(fname); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(fname); Swig_banner_target_lang(goopsfile, ";;;"); @@ -947,20 +947,16 @@ public: if (!is_setter) { /* Strip off "-get" */ - char *pws_name = (char *) malloc(sizeof(char) * (len - 3)); - strncpy(pws_name, pc, len - 3); - pws_name[len - 4] = 0; if (struct_member == 2) { /* There was a setter, so create a procedure with setter */ Printf(f_init, "scm_c_define"); - Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(getter, setter));\n", pws_name); + Printf(f_init, "(\"%.*s\", " "scm_make_procedure_with_setter(getter, setter));\n", pc, len - 4); } else { /* There was no setter, so make an alias to the getter */ Printf(f_init, "scm_c_define"); - Printf(f_init, "(\"%s\", getter);\n", pws_name); + Printf(f_init, "(\"%.*s\", getter);\n", pc, len - 4); } - Printf(exported_symbols, "\"%s\", ", pws_name); - free(pws_name); + Printf(exported_symbols, "\"%.*s\", ", pc, len - 4); } } else { /* Register the function */ diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx index fee6cd7da..5a9242399 100644 --- a/Source/Modules/interface.cxx +++ b/Source/Modules/interface.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * interface.cxx * @@ -15,6 +15,7 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" +#include "cparse.h" static bool interface_feature_enabled = false; @@ -28,25 +29,31 @@ static bool interface_feature_enabled = false; static List *collect_interface_methods(Node *n) { List *methods = NewList(); - if (Hash *bases = Getattr(n, "interface:bases")) { - List *keys = Keys(bases); - for (Iterator base = First(keys); base.item; base = Next(base)) { - Node *cls = Getattr(bases, base.item); + if (List *bases = Getattr(n, "interface:bases")) { + for (Iterator base = First(bases); base.item; base = Next(base)) { + Node *cls = base.item; if (cls == n) continue; for (Node *child = firstChild(cls); child; child = nextSibling(child)) { if (Cmp(nodeType(child), "cdecl") == 0) { if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner")) continue; // skip methods propagated to bases - Node *m = Copy(child); - set_nextSibling(m, NIL); - set_previousSibling(m, NIL); - Setattr(m, "interface:owner", cls); - Append(methods, m); + if (!checkAttribute(child, "kind", "function")) + continue; + if (checkAttribute(child, "storage", "static")) + continue; // accept virtual methods, non-virtual methods too... mmm??. Warn that the interface class has something that is not a virtual method? + Node *nn = copyNode(child); + Setattr(nn, "interface:owner", cls); + ParmList *parms = CopyParmList(Getattr(child, "parms")); + Setattr(nn, "parms", parms); + Delete(parms); + ParmList *throw_parm_list = Getattr(child, "throws"); + if (throw_parm_list) + Setattr(nn, "throws", CopyParmList(throw_parm_list)); + Append(methods, nn); } } } - Delete(keys); } return methods; } @@ -55,17 +62,17 @@ static List *collect_interface_methods(Node *n) { * collect_interface_bases * ----------------------------------------------------------------------------- */ -static void collect_interface_bases(Hash *bases, Node *n) { - if (Getattr(n, "feature:interface")) { +static void collect_interface_bases(List *bases, Node *n) { + if (GetFlag(n, "feature:interface")) { String *name = Getattr(n, "interface:name"); if (!Getattr(bases, name)) - Setattr(bases, name, n); + Append(bases, n); } if (List *baselist = Getattr(n, "bases")) { for (Iterator base = First(baselist); base.item; base = Next(base)) { if (!GetFlag(base.item, "feature:ignore")) { - if (Getattr(base.item, "feature:interface")) + if (GetFlag(base.item, "feature:interface")) collect_interface_bases(bases, base.item); } } @@ -83,21 +90,21 @@ static void collect_interface_bases(Hash *bases, Node *n) { * ----------------------------------------------------------------------------- */ static void collect_interface_base_classes(Node *n) { - if (Getattr(n, "feature:interface")) { + if (GetFlag(n, "feature:interface")) { // check all bases are also interfaces if (List *baselist = Getattr(n, "bases")) { for (Iterator base = First(baselist); base.item; base = Next(base)) { if (!GetFlag(base.item, "feature:ignore")) { - if (!Getattr(base.item, "feature:interface")) { + if (!GetFlag(base.item, "feature:interface")) { Swig_error(Getfile(n), Getline(n), "Base class '%s' of '%s' is not similarly marked as an interface.\n", SwigType_namestr(Getattr(base.item, "name")), SwigType_namestr(Getattr(n, "name"))); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } } } } - Hash *interface_bases = NewHash(); + List *interface_bases = NewList(); collect_interface_bases(interface_bases, n); if (Len(interface_bases) == 0) Delete(interface_bases); @@ -110,11 +117,11 @@ static void collect_interface_base_classes(Node *n) { * ----------------------------------------------------------------------------- */ static void process_interface_name(Node *n) { - if (Getattr(n, "feature:interface")) { + if (GetFlag(n, "feature:interface")) { String *interface_name = Getattr(n, "feature:interface:name"); if (!Len(interface_name)) { Swig_error(Getfile(n), Getline(n), "The interface feature for '%s' is missing the name attribute.\n", SwigType_namestr(Getattr(n, "name"))); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (Strchr(interface_name, '%')) { String *name = NewStringf(interface_name, Getattr(n, "sym:name")); @@ -139,7 +146,7 @@ void Swig_interface_propagate_methods(Node *n) { process_interface_name(n); collect_interface_base_classes(n); List *methods = collect_interface_methods(n); - bool is_interface = Getattr(n, "feature:interface") != 0; + bool is_interface = GetFlag(n, "feature:interface") ? true : false; for (Iterator mi = First(methods); mi.item; mi = Next(mi)) { if (!is_interface && GetFlag(mi.item, "abstract")) continue; @@ -164,8 +171,25 @@ void Swig_interface_propagate_methods(Node *n) { } Delete(this_decl_resolved); if (!identically_overloaded_method) { - // TODO: Fix if the method is overloaded with different arguments / has default args - appendChild(n, mi.item); + // Add method copied from base class to this derived class + Node *cn = mi.item; + Delattr(cn, "sym:overname"); + String *prefix = Getattr(n, "name"); + String *name = Getattr(cn, "name"); + String *decl = Getattr(cn, "decl"); + String *oldname = Getattr(cn, "sym:name"); + + String *symname = Swig_name_make(cn, prefix, name, decl, oldname); + if (Strcmp(symname, "$ignore") != 0) { + Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab")); + Node *on = Swig_symbol_add(symname, cn); + assert(on == cn); + + // Features from the copied base class method are already present, now add in features specific to the added method in the derived class + Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn); + Swig_symbol_setscope(oldscope); + appendChild(n, cn); + } } else { Delete(mi.item); } diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 444fe02d1..93d623703 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * java.cxx * @@ -12,8 +12,8 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" -#include <limits.h> // for INT_MAX #include "cparse.h" +#include <limits.h> // for INT_MAX #include <ctype.h> #include "javadoc.h" @@ -371,24 +371,24 @@ public: if (!outfile) { Printf(stderr, "Unable to determine outfile\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (directorsEnabled()) { if (!outfile_h) { Printf(stderr, "Unable to determine outfile_h\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -521,7 +521,7 @@ public: File *f_im = NewFile(filen, "w", SWIG_output_files()); if (!f_im) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -576,7 +576,7 @@ public: File *f_module = NewFile(filen, "w", SWIG_output_files()); if (!f_module) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -635,7 +635,7 @@ public: File *f_module = NewFile(filen, "w", SWIG_output_files()); if (!f_module) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -1332,10 +1332,7 @@ public: // Add extra indentation Replaceall(enum_code, "\n", "\n "); Replaceall(enum_code, " \n", "\n"); - if (GetFlag(getCurrentClass(), "feature:interface")) - Printv(interface_class_code, " ", enum_code, "\n\n", NIL); - else - Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); + Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); } else { // Global enums are defined in their own file String *output_directory = outputDirectory(nspace); @@ -1343,7 +1340,7 @@ public: File *f_enum = NewFile(filen, "w", SWIG_output_files()); if (!f_enum) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -1843,10 +1840,9 @@ public: * addInterfaceNameAndUpcasts() * ----------------------------------------------------------------------------- */ - void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) { - List *keys = Keys(base_list); - for (Iterator it = First(keys); it.item; it = Next(it)) { - Node *base = Getattr(base_list, it.item); + void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) { + for (Iterator it = First(base_list); it.item; it = Next(it)) { + Node *base = it.item; SwigType *c_baseclassname = Getattr(base, "name"); String *interface_name = Getattr(base, "interface:name"); if (Len(interface_list)) @@ -1873,7 +1869,6 @@ public: Delete(cptr_method_name); Delete(interface_code); } - Delete(keys); } /* ----------------------------------------------------------------------------- @@ -1959,7 +1954,7 @@ public: if (baselist) { Iterator base = First(baselist); while (base.item) { - if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) { + if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) { SwigType *baseclassname = Getattr(base.item, "name"); if (!c_baseclassname) { String *name = getProxyName(baseclassname); @@ -1979,7 +1974,7 @@ public: } } - Hash *interface_bases = Getattr(n, "interface:bases"); + List *interface_bases = Getattr(n, "interface:bases"); if (interface_bases) addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname); @@ -2140,7 +2135,7 @@ public: if (List *baselist = Getattr(n, "bases")) { String *bases = 0; for (Iterator base = First(baselist); base.item; base = Next(base)) { - if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface")) + if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface")) continue; // TODO: warn about skipped non-interface bases String *base_iname = Getattr(base.item, "interface:name"); if (!bases) @@ -2215,12 +2210,12 @@ public: if (Cmp(proxy_class_name, imclass_name) == 0) { Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (Cmp(proxy_class_name, module_class_name) == 0) { Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } else { if (outerClassesPrefix) { @@ -2236,7 +2231,7 @@ public: } } - String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0; + String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0; if (outerClassesPrefix) { String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; if (!addSymbol(proxy_class_name, n, fnspace)) @@ -2260,7 +2255,7 @@ public: f_proxy = NewFile(filen, "w", SWIG_output_files()); if (!f_proxy) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -2287,14 +2282,14 @@ public: destructor_throws_clause = NewString(""); proxy_class_constants_code = NewString(""); - if (Getattr(n, "feature:interface")) { + if (GetFlag(n, "feature:interface")) { interface_class_code = NewString(""); String *output_directory = outputDirectory(nspace); String *filen = NewStringf("%s%s.java", output_directory, interface_name); f_interface = NewFile(filen, "w", SWIG_output_files()); if (!f_interface) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, filen); // file name ownership goes to the list emitBanner(f_interface); @@ -2462,7 +2457,7 @@ public: bool setter_flag = false; String *pre_code = NewString(""); String *post_code = NewString(""); - bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 + bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable") && !static_flag && Getattr(n, "interface:owner") == 0; if (!proxy_flag) @@ -2694,6 +2689,7 @@ public: Replaceall(imcall, "$imfuncname", intermediary_function_name); } + Replaceall(tm, "$imfuncname", intermediary_function_name); Replaceall(tm, "$jnicall", imcall); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0)); @@ -3179,6 +3175,7 @@ public: else Replaceall(tm, "$owner", "false"); substituteClassname(t, tm); + Replaceall(tm, "$imfuncname", overloaded_name); Replaceall(tm, "$jnicall", imcall); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0)); @@ -3497,7 +3494,7 @@ public: File *f_swigtype = NewFile(filen, "w", SWIG_output_files()); if (!f_swigtype) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Append(filenames_list, Copy(filen)); Delete(filen); @@ -3712,7 +3709,7 @@ public: if (newdir_error) { Printf(stderr, "%s\n", newdir_error); Delete(newdir_error); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); Delete(nspace_subdirectory); diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 01b577e20..bf0f471b0 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * javascript.cxx * @@ -537,21 +537,21 @@ void JAVASCRIPT::main(int argc, char *argv[]) { if (strcmp(argv[i], "-v8") == 0) { if (engine != -1) { Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE); - SWIG_exit(-1); + Exit(EXIT_FAILURE); } Swig_mark_arg(i); engine = JSEmitter::V8; } else if (strcmp(argv[i], "-jsc") == 0) { if (engine != -1) { Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE); - SWIG_exit(-1); + Exit(EXIT_FAILURE); } Swig_mark_arg(i); engine = JSEmitter::JavascriptCore; } else if (strcmp(argv[i], "-node") == 0) { if (engine != -1) { Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE); - SWIG_exit(-1); + Exit(EXIT_FAILURE); } Swig_mark_arg(i); engine = JSEmitter::NodeJS; @@ -595,7 +595,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { default: { Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n"); - SWIG_exit(-1); + Exit(EXIT_FAILURE); break; } } @@ -666,7 +666,7 @@ Template JSEmitter::getTemplate(const String *name) { if (!templ) { Printf(stderr, "Could not find template %s\n.", name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Template t(templ, name); @@ -760,13 +760,10 @@ int JSEmitter::emitWrapperFunction(Node *n) { ret = emitSetter(n, is_member, is_static); } else if (is_getter) { ret = emitGetter(n, is_member, is_static); - } else { - Swig_print_node(n); } } else { Printf(stderr, "Warning: unsupported wrapper function type\n"); - Swig_print_node(n); ret = SWIG_ERROR; } } else { @@ -778,7 +775,6 @@ int JSEmitter::emitWrapperFunction(Node *n) { ret = emitDtor(n); } else { Printf(stderr, "Warning: unsupported wrapper function type"); - Swig_print_node(n); ret = SWIG_ERROR; } } @@ -936,7 +932,7 @@ int JSEmitter::emitDtor(Node *n) { SwigType *type = state.clazz(TYPE); String *p_classtype = SwigType_add_pointer(state.clazz(TYPE)); String *ctype = SwigType_lstr(p_classtype, ""); - String *free = NewString(""); + String *jsfree = NewString(""); // (Taken from JSCore implementation.) /* The if (Extend) block was taken from the Ruby implementation. @@ -979,9 +975,9 @@ int JSEmitter::emitDtor(Node *n) { // TODO: generate dtors more similar to other wrappers // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used. if (SwigType_isarray(type)) { - Printf(free, "delete [] (%s)", ctype); + Printf(jsfree, "delete [] (%s)", ctype); } else { - Printf(free, "delete (%s)", ctype); + Printf(jsfree, "delete (%s)", ctype); } String *destructor_action = Getattr(n, "wrap:action"); @@ -1031,7 +1027,7 @@ int JSEmitter::emitDtor(Node *n) { state.clazz(DTOR, wrap_name); t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) .replace("$jswrapper", wrap_name) - .replace("$jsfree", free) + .replace("$jsfree", jsfree) .replace("$jstype", ctype); t_dtor.replace("${destructor_action}", destructor_action); @@ -1041,14 +1037,14 @@ int JSEmitter::emitDtor(Node *n) { state.clazz(DTOR, wrap_name); t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .replace("$jswrapper", wrap_name) - .replace("$jsfree", free) + .replace("$jsfree", jsfree) .replace("$jstype", ctype) .pretty_print(f_wrappers); } Delete(p_classtype); Delete(ctype); - Delete(free); + Delete(jsfree); return SWIG_OK; } @@ -1409,7 +1405,6 @@ int JSEmitter::switchNamespace(Node *n) { String *_nspace = lang->getNSpace(); if (!Equal(nspace, _nspace)) { Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace); - Swig_print_node(n); } #endif @@ -1576,7 +1571,7 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma break; default: Printf(stderr, "Illegal MarshallingMode."); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } tm = emitInputTypemap(n, p, wrapper, arg); Delete(arg); @@ -1599,7 +1594,7 @@ int JSCEmitter::initialize(Node *n) { f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); if (!f_wrap_cpp) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } /* Initialization of members */ @@ -1620,6 +1615,8 @@ int JSCEmitter::initialize(Node *n) { Swig_banner(f_wrap_cpp); + Printf(f_runtime, "#ifndef SWIGJAVASCRIPT\n#define SWIGJAVASCRIPT\n#endif\n\n"); + return SWIG_OK; } @@ -1920,7 +1917,7 @@ int V8Emitter::initialize(Node *n) { f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); if (!f_wrap_cpp) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); @@ -1950,6 +1947,8 @@ int V8Emitter::initialize(Node *n) { Swig_banner(f_wrap_cpp); + Printf(f_runtime, "#ifndef SWIGJAVASCRIPT\n#define SWIGJAVASCRIPT\n#endif\n\n"); + return SWIG_OK; } @@ -2214,7 +2213,7 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar break; default: Printf(stderr, "Illegal MarshallingMode."); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } tm = emitInputTypemap(n, p, wrapper, arg); @@ -2370,7 +2369,7 @@ Template::Template(const String *code_) { if (!code_) { Printf(stdout, "Template code was null. Illegal input for template."); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } code = NewString(code_); templateName = NewString(""); @@ -2380,7 +2379,7 @@ Template::Template(const String *code_, const String *templateName_) { if (!code_) { Printf(stdout, "Template code was null. Illegal input for template."); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } code = NewString(code_); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 196ff47a9..1e10e51d6 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * lang.cxx * @@ -77,6 +77,9 @@ static Hash *classhash; extern int GenerateDefault; extern int ForceExtern; extern int AddExtern; +extern "C" { + extern int UseWrapperSuffix; +} /* import modes */ @@ -1324,7 +1327,7 @@ int Language::staticmemberfunctionHandler(Node *n) { // See Swig_MethodToFunction() for the explanation of this code. if (Getattr(n, "sym:overloaded")) { Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname")); - } else { + } else if (UseWrapperSuffix) { Append(cname, "__SWIG"); } @@ -1845,20 +1848,82 @@ static String *vtable_method_id(Node *n) { String *tmp = SwigType_pop_function(local_decl); Delete(local_decl); local_decl = tmp; - Node *method_id = NewStringf("%s|%s", name, local_decl); + String *method_id = NewStringf("%s|%s", name, local_decl); Delete(local_decl); return method_id; } +/* ---------------------------------------------------------------------- + * Language::unrollOneVirtualMethod() + * ---------------------------------------------------------------------- */ + +void Language::unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) { + if (!checkAttribute(n, "storage", "virtual")) + return; + if (GetFlag(n, "final")) + return; + + String *nodeType = Getattr(n, "nodeType"); + + /* 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) { + String *decl = Getattr(n, "decl"); + /* extra check for function type and proper access */ + if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(n)) || need_nonpublic_member(n))) { + String *name = Getattr(n, "name"); + String *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(n); + /* Make sure that the new method overwrites the existing: */ + int len = Len(vm); + const int DO_NOT_REPLACE = -1; + int replace = DO_NOT_REPLACE; + for (int i = 0; i < len; i++) { + Node *item = Getitem(vm, i); + String *check_vmid = Getattr(item, "vmid"); + + if (Strcmp(method_id, check_vmid) == 0) { + replace = i; + break; + } + } + /* filling a new method item */ + String *fqdname = NewStringf("%s::%s", classname, name); + Hash *item = NewHash(); + Setattr(item, "fqdname", fqdname); + Node *m = Copy(n); + + /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */ + SwigType *ty = NewString(Getattr(m, "type")); + SwigType_push(ty, decl); + if (SwigType_isqualifier(ty)) { + Delete(SwigType_pop(ty)); + } + Delete(SwigType_pop_function(ty)); + Setattr(m, "returntype", ty); + + String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name); + /* apply the features of the original method found in the base class */ + Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m); + Setattr(item, "methodNode", m); + Setattr(item, "vmid", method_id); + if (replace == DO_NOT_REPLACE) + Append(vm, item); + else + Setitem(vm, replace, item); + Setattr(n, "directorNode", m); + + Delete(mname); + } + if (is_destructor) { + virtual_destructor = 1; + } + } +} /* ---------------------------------------------------------------------- * Language::unrollVirtualMethods() * ---------------------------------------------------------------------- */ -int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) { - Node *ni; - String *nodeType; - String *classname; - String *decl; +int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) { bool first_base = false; // recurse through all base classes to build the vtable List *bl = Getattr(n, "bases"); @@ -1867,10 +1932,11 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_ for (bi = First(bl); bi.item; bi = Next(bi)) { if (first_base && !director_multiple_inheritance) break; - unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor); + unrollVirtualMethods(bi.item, parent, vm, virtual_destructor); first_base = true; } } + // recurse through all protected base classes to build the vtable, as needed bl = Getattr(n, "protectedbases"); if (bl) { @@ -1878,88 +1944,28 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_ for (bi = First(bl); bi.item; bi = Next(bi)) { if (first_base && !director_multiple_inheritance) break; - unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1); + unrollVirtualMethods(bi.item, parent, vm, virtual_destructor, 1); first_base = true; } } + // find the methods that need directors - classname = Getattr(n, "name"); - for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { + String *classname = Getattr(n, "name"); + for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) { /* we only need to check the virtual members */ - nodeType = Getattr(ni, "nodeType"); - int is_using = (Cmp(nodeType, "using") == 0); - Node *nn = is_using ? firstChild(ni) : ni; /* assume there is only one child node for "using" nodes */ - if (is_using) { - if (nn) - nodeType = Getattr(nn, "nodeType"); - else - continue; // A private "using" node - } - 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) { - decl = Getattr(nn, "decl"); - /* extra check for function type and proper access */ - if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(nn)) || need_nonpublic_member(nn))) { - String *name = Getattr(nn, "name"); - Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(nn); - /* Make sure that the new method overwrites the existing: */ - int len = Len(vm); - const int DO_NOT_REPLACE = -1; - int replace = DO_NOT_REPLACE; - for (int i = 0; i < len; i++) { - Node *item = Getitem(vm, i); - String *check_vmid = Getattr(item, "vmid"); - - if (Strcmp(method_id, check_vmid) == 0) { - replace = i; - break; - } - } - /* filling a new method item */ - String *fqdname = NewStringf("%s::%s", classname, name); - Hash *item = NewHash(); - Setattr(item, "fqdname", fqdname); - Node *m = Copy(nn); - - /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */ - SwigType *ty = NewString(Getattr(m, "type")); - SwigType_push(ty, decl); - if (SwigType_isqualifier(ty)) { - Delete(SwigType_pop(ty)); - } - Delete(SwigType_pop_function(ty)); - Setattr(m, "returntype", ty); - - String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name); - /* apply the features of the original method found in the base class */ - Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m); - Setattr(item, "methodNode", m); - Setattr(item, "vmid", method_id); - if (replace == DO_NOT_REPLACE) - Append(vm, item); - else - Setitem(vm, replace, item); - Setattr(nn, "directorNode", m); - - Delete(mname); - } - if (is_destructor) { - virtual_destructor = 1; + if (Equal(nodeType(ni), "using")) { + for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) { + unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase); } } + unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase); } /* We delete all the nodirector methods. This prevents the generation of 'empty' director classes. - But this has to be done outside the previous 'for' - and the recursive loop!. + Done once we've collated all the virtual methods into vm. */ if (n == parent) { int len = Len(vm); @@ -2196,7 +2202,7 @@ int Language::classDirector(Node *n) { } List *vtable = NewList(); int virtual_destructor = 0; - unrollVirtualMethods(n, n, vtable, 0, virtual_destructor); + unrollVirtualMethods(n, n, vtable, virtual_destructor); // Emit all the using base::member statements for non virtual members (allprotected mode) Node *ni; @@ -3788,7 +3794,7 @@ int Language::abstractClassTest(Node *n) { #endif for (int i = 0; i < labs; i++) { Node *ni = Getitem(abstracts, i); - Node *method_id = vtable_method_id(ni); + String *method_id = vtable_method_id(ni); if (!method_id) continue; bool exists_item = false; diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index f92c14cb2..855acc69d 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * lua.cxx * @@ -304,7 +304,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); @@ -1418,7 +1418,6 @@ public: List *baselist = Getattr(n, "bases"); if (baselist && Len(baselist)) { Iterator b; - int index = 0; b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "name"); @@ -1431,7 +1430,6 @@ public: Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname)); b = Next(b); - index++; } } // First, print class static part diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index ebd788d35..d2960e9f8 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * main.cxx * @@ -37,9 +37,13 @@ int Verbose = 0; int AddExtern = 0; int NoExcept = 0; int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime +extern "C" { + int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too. +} + +/* Suppress warning messages for private inheritance, etc by default. + These are enabled by command line option -Wextra. -/* Suppress warning messages for private inheritance, preprocessor evaluation etc... - WARN_PP_EVALUATION 202 WARN_PARSE_PRIVATE_INHERIT 309 WARN_PARSE_BUILTIN_NAME 321 WARN_PARSE_REDUNDANT 322 @@ -47,7 +51,7 @@ int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 WARN_LANG_OVERLOAD_CONST 512 */ -#define EXTRA_WARNINGS "202,309,403,405,512,321,322" +#define EXTRA_WARNINGS "309,403,405,512,321,322" extern "C" { extern String *ModuleName; @@ -74,6 +78,7 @@ static const char *usage1 = (const char *) "\ -debug-symbols - Display target language symbols in the symbol tables\n\ -debug-csymbols - Display C symbols in the symbol tables\n\ -debug-lsymbols - Display target language layer symbols\n\ + -debug-quiet - Display less parse tree node debug info when using other -debug options\n\ -debug-tags - Display information about the tags found in the interface\n\ -debug-template - Display information for debugging templates\n\ -debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages\n\ @@ -193,7 +198,6 @@ static int dump_tags = 0; static int dump_module = 0; static int dump_top = 0; static int dump_xml = 0; -static int browse = 0; static int dump_typedef = 0; static int dump_classes = 0; static int werror = 0; @@ -403,14 +407,14 @@ static void SWIG_dump_runtime() { outfile = lang->defaultExternalRuntimeFilename(); if (!outfile) { Printf(stderr, "*** Please provide a filename for the external runtime\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } runtime = NewFile(outfile, "w", SWIG_output_files()); if (!runtime) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Swig_banner(runtime); @@ -420,7 +424,7 @@ static void SWIG_dump_runtime() { if (!s) { Printf(stderr, "*** Unable to open 'swiglabels.swg'\n"); Delete(runtime); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printf(runtime, "%s", s); Delete(s); @@ -429,7 +433,7 @@ static void SWIG_dump_runtime() { if (!s) { Printf(stderr, "*** Unable to open 'swigerrors.swg'\n"); Delete(runtime); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printf(runtime, "%s", s); Delete(s); @@ -438,7 +442,7 @@ static void SWIG_dump_runtime() { if (!s) { Printf(stderr, "*** Unable to open 'swigrun.swg'\n"); Delete(runtime); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printf(runtime, "%s", s); Delete(s); @@ -451,13 +455,13 @@ static void SWIG_dump_runtime() { if (!s) { Printf(stderr, "*** Unable to open 'runtime.swg'\n"); Delete(runtime); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printf(runtime, "%s", s); Delete(s); Delete(runtime); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } static void getoptions(int argc, char *argv[]) { @@ -471,9 +475,7 @@ static void getoptions(int argc, char *argv[]) { Swig_mark_arg(i); } else if (strncmp(argv[i], "-I", 2) == 0) { // Add a new directory search path - char *a = Swig_copy_string(argv[i] + 2); - Swig_add_directory((DOH *) a); - free(a); + Swig_add_directory((String_or_char*)(argv[i] + 2)); Swig_mark_arg(i); } else if (strncmp(argv[i], "-D", 2) == 0) { String *d = NewString(argv[i] + 2); @@ -533,7 +535,7 @@ static void getoptions(int argc, char *argv[]) { Printf(stdout, "%s\n", version); Delete(version); Swig_mark_arg(i); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-small") == 0) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); @@ -596,7 +598,7 @@ static void getoptions(int argc, char *argv[]) { Printf(stdout, "%s\n", SwigLib); if (SwigLibWinUnix) Printf(stdout, "%s\n", SwigLibWinUnix); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-o") == 0) { Swig_mark_arg(i); if (argv[i + 1]) { @@ -649,7 +651,7 @@ static void getoptions(int argc, char *argv[]) { #endif ); fprintf(stdout, "\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-copyright") == 0) { fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version()); fprintf(stdout, "Copyright (c) 1995-1998\n"); @@ -658,7 +660,7 @@ static void getoptions(int argc, char *argv[]) { fprintf(stdout, "University of Chicago\n"); fprintf(stdout, "Copyright (c) 2005-2006\n"); fprintf(stdout, "Arizona Board of Regents (University of Arizona)\n"); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } else if (strncmp(argv[i], "-l", 2) == 0) { // Add a new directory search path Append(libfiles, argv[i] + 2); @@ -780,6 +782,9 @@ static void getoptions(int argc, char *argv[]) { } else if (strncmp(argv[i], "-w", 2) == 0) { Swig_mark_arg(i); Swig_warnfilter(argv[i] + 2, 1); + } else if (strcmp(argv[i], "-debug-quiet") == 0) { + Swig_print_quiet(1); + Swig_mark_arg(i); } else if (strcmp(argv[i], "-debug-symtabs") == 0) { dump_symtabs = 1; Swig_mark_arg(i); @@ -848,9 +853,6 @@ static void getoptions(int argc, char *argv[]) { } else if (strcmp(argv[i], "-nocontract") == 0) { Swig_mark_arg(i); Swig_contract_mode_set(0); - } else if (strcmp(argv[i], "-browse") == 0) { - browse = 1; - Swig_mark_arg(i); } else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) { dump_typedef = 1; Swig_mark_arg(i); @@ -882,9 +884,14 @@ static void getoptions(int argc, char *argv[]) { } } +static void SWIG_exit_handler(int status); + int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { char *c; + /* Set function for Exit() to call. */ + SetExitHandler(SWIG_exit_handler); + /* Initialize the SWIG core */ Swig_init(); @@ -971,7 +978,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (help) { Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n"); - SWIG_exit(EXIT_SUCCESS); // Exit if we're in help mode + Exit(EXIT_SUCCESS); // Exit if we're in help mode } // Check all of the options to make sure we're cool. @@ -980,7 +987,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (CPlusPlus && cparse_cplusplusout) { Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } install_opts(argc, argv); @@ -1045,7 +1052,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { File *f_outfile = NewFile(outfile, "w", SWIG_output_files()); if (!f_outfile) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else { if (Verbose) Printf(stdout, "'%s' checked out from the SWIG library.\n", outfile); @@ -1073,7 +1080,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { } else { Printf(stderr, "Unable to find file '%s'.\n", input_file); } - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else { 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 } @@ -1082,7 +1089,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (!tlm) { Printf(stderr, "No target language specified.\n"); Printf(stderr, "Use 'swig -help' for more information.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (!no_cpp) { @@ -1106,11 +1113,11 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { fclose(df); } if (Swig_error_count()) { - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (cpp_only) { Printf(stdout, "%s", cpps); - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); } if (depend) { if (!no_cpp) { @@ -1132,14 +1139,14 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { f_dependencies_file = NewFile(dependencies_file, "w", SWIG_output_files()); if (!f_dependencies_file) { FileErrorDisplay(dependencies_file); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } else if (!depend_only) { String *filename = NewStringf("%s_wrap.%s", basename, depends_extension); f_dependencies_file = NewFile(filename, "w", SWIG_output_files()); if (!f_dependencies_file) { FileErrorDisplay(filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } else f_dependencies_file = stdout; @@ -1172,14 +1179,14 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (f_dependencies_file != stdout) Delete(f_dependencies_file); if (depend_only) - SWIG_exit(EXIT_SUCCESS); + Exit(EXIT_SUCCESS); Delete(inputfile_filename); Delete(basename); Delete(phony_targets); } else { Printf(stderr, "Cannot generate dependencies with -nopreprocess\n"); // Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } Seek(cpps, 0, SEEK_SET); @@ -1284,13 +1291,13 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (top) { if (!Getattr(top, "name")) { Printf(stderr, "No module name specified using %%module or -module.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else { /* Set some filename information on the object */ String *infile = scanner_get_main_input_file(); if (!infile) { Printf(stderr, "Missing input file in preprocessed output.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file Setattr(top, "inputfile", input_file); @@ -1322,15 +1329,12 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (tlm->status == Experimental) { Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. " "Target language %s specified by %s is an experimental language. " - "Please read about SWIG experimental languages, http://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n", + "Please read about SWIG experimental languages, https://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n", tlm->help ? tlm->help : "", tlm->name); } lang->top(top); - if (browse) { - Swig_browser(top, 0); - } Delete(infile_filename); Delete(basename); } @@ -1364,7 +1368,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { if (!f_outfiles) { Printf(stderr, "Failed to write list of output files to the filename '%s' specified in CCACHE_OUTFILES environment variable - ", outfiles); FileErrorDisplay(outfiles); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else { int i; for (i = 0; i < Len(all_output_files); i++) @@ -1386,22 +1390,22 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { error_count += Swig_error_count(); if (error_count != 0) - SWIG_exit(error_count); + Exit(EXIT_FAILURE); return 0; } /* ----------------------------------------------------------------------------- - * SWIG_exit() + * SWIG_exit_handler() * * Cleanup and either freeze or exit * ----------------------------------------------------------------------------- */ -void SWIG_exit(int exit_code) { +static void SWIG_exit_handler(int status) { while (freeze) { } - if (exit_code > 0) { + if (status > 0) { CloseAllOpenFiles(); /* Remove all generated files */ @@ -1414,6 +1418,4 @@ void SWIG_exit(int exit_code) { } } } - - exit(exit_code); } diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 3ff691662..6e412a09c 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * mzscheme.cxx * @@ -12,7 +12,6 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" - #include <ctype.h> static const char *usage = "\ @@ -66,7 +65,7 @@ public: if (argv[i]) { if (strcmp(argv[i], "-help") == 0) { fputs(usage, stdout); - SWIG_exit(0); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = NewString(argv[i + 1]); @@ -130,7 +129,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx index 808ee5d05..d027eebe5 100644 --- a/Source/Modules/nested.cxx +++ b/Source/Modules/nested.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * nested.cxx * diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index a36912ab7..7ea453132 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * ocaml.cxx * @@ -12,7 +12,6 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" - #include <ctype.h> static const char *usage = "\ @@ -99,10 +98,10 @@ public: if (argv[i]) { if (strcmp(argv[i], "-help") == 0) { fputs(usage, stdout); - SWIG_exit(0); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-where") == 0) { PrintIncludeArg(); - SWIG_exit(0); + Exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = NewString(argv[i + 1]); @@ -228,7 +227,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); @@ -311,12 +310,12 @@ public: String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile); if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) { FileErrorDisplay(mlfilen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile); if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) { FileErrorDisplay(mlifilen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } emitBanner(f_mlout); emitBanner(f_mliout); @@ -398,26 +397,18 @@ public: */ void oc_SwigType_del_reference(SwigType *t) { - char *c = Char(t); - if (strncmp(c, "q(", 2) == 0) { - Delete(SwigType_pop(t)); - c = Char(t); - } - if (strncmp(c, "r.", 2)) { - printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n"); - abort(); + if (SwigType_isqualifier(t)) { + SwigType_del_qualifier(t); } - Replace(t, "r.", "", DOH_REPLACE_FIRST); + SwigType_del_reference(t); } void oc_SwigType_del_array(SwigType *t) { - char *c = Char(t); - if (strncmp(c, "q(", 2) == 0) { - Delete(SwigType_pop(t)); - c = Char(t); + if (SwigType_isqualifier(t)) { + SwigType_del_qualifier(t); } - if (strncmp(c, "a(", 2) == 0) { - Delete(SwigType_pop(t)); + if (SwigType_isarray(t)) { + SwigType_del_array(t); } } @@ -1247,6 +1238,7 @@ public: int enumvalueDeclaration(Node *n) { String *name = Getattr(n, "name"); + String *symname = Getattr(n, "sym:name"); SwigType *qtype = 0; if (name_qualifier_type) { @@ -1254,8 +1246,8 @@ public: Printv(qtype, name, NIL); } - if (const_enum && qtype && name && !Getattr(seen_enumvalues, name)) { - Setattr(seen_enumvalues, name, "true"); + if (const_enum && qtype && symname && !Getattr(seen_enumvalues, symname)) { + Setattr(seen_enumvalues, symname, "true"); SetFlag(n, "feature:immutable"); Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used @@ -1264,10 +1256,10 @@ public: String *evname = SwigType_manglestr(qtype); Insert(evname, 0, "SWIG_ENUM_"); - Setattr(n, "feature:enumvname", name); + Setattr(n, "feature:enumvname", symname); Setattr(n, "feature:symname", evname); Delete(evname); - Printf(f_enumtypes_value, "| `%s\n", name); + Printf(f_enumtypes_value, "| `%s\n", symname); return Language::enumvalueDeclaration(n); } else @@ -1495,10 +1487,6 @@ public: int i; char source[256]; - int outputs = 0; - if (!is_void) - outputs++; - /* build argument list and type conversion string */ for (i = 0, idx = 0, p = l; i < num_arguments; i++) { @@ -1506,9 +1494,6 @@ public: p = Getattr(p, "tmap:ignore:next"); } - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - String *pname = Getattr(p, "name"); String *ptype = Getattr(p, "type"); diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 04b315eaf..04609b017 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * octave.cxx * @@ -119,7 +119,7 @@ public: } else if (strcmp(argv[i], "-nocppcast") == 0) { Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); Swig_mark_arg(i); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } } @@ -167,7 +167,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_header = NewString(""); @@ -835,7 +835,7 @@ public: String *setwname = Swig_name_wrapper(setname); Octave_begin_function(n, setf->def, setname, setwname, true); - Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname); + Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();\n", iname); if (is_assignable(n)) { Setattr(n, "wrap:name", setname); if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { @@ -1003,7 +1003,6 @@ public: List *baselist = Getattr(n, "bases"); if (baselist && Len(baselist)) { Iterator b; - int index = 0; b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "name"); @@ -1016,7 +1015,6 @@ public: Printf(base_class_names, "\"%s\",", bname_mangled); Printf(base_class, "0,"); b = Next(b); - index++; Delete(bname_mangled); } } diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx index 8a4ce48f7..b94e87ebb 100644 --- a/Source/Modules/overload.cxx +++ b/Source/Modules/overload.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * overload.cxx * @@ -339,7 +339,6 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { Setattr(nodes[i].n, "overload:ignore", "1"); Append(result, nodes[i].n); // Printf(stdout,"[ %d ] %d %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms)); - // Swig_print_node(nodes[i].n); if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) { if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) { // Add additional implicitconv functions in same order as already ranked. @@ -351,7 +350,6 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { SetFlag(nodes[j].n, "implicitconvtypecheckoff"); Append(result, nodes[j].n); // Printf(stdout,"[ %d ] %d + %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms)); - // Swig_print_node(nodes[j].n); } } } diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index 459d403bf..add4fd0b6 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * perl5.cxx * @@ -21,7 +21,7 @@ Perl 5 Options (available with -perl5)\n\ -const - Wrap constants as constants and not variables (implies -proxy)\n\ -nopm - Do not generate the .pm file\n\ -noproxy - Don't create proxy classes\n\ - -proxy - Create proxy classes\n\ + -proxy - Create proxy classes (enabled by default)\n\ -static - Omit code related to dynamic loading\n\ \n"; @@ -154,11 +154,11 @@ public: if (strcmp(argv[i], "-package") == 0) { Printv(stderr, "*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else if (strcmp(argv[i], "-interface") == 0) { Printv(stderr, "*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else if (strcmp(argv[i], "-exportall") == 0) { export_all = 1; Swig_mark_arg(i); @@ -197,7 +197,7 @@ public: } else if (strcmp(argv[i], "-nocppcast") == 0) { Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); Swig_mark_arg(i); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } } @@ -276,7 +276,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); @@ -289,7 +289,7 @@ public: f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -407,7 +407,7 @@ public: String *filen = NewStringf("%s%s", SWIG_output_directory(), pmfile); if ((f_pm = NewFile(filen, "w", SWIG_output_files())) == 0) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(filen); filen = NULL; diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 6862c214b..13b3df686 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * php.cxx * @@ -13,9 +13,10 @@ */ #include "swigmod.h" - +#include <algorithm> #include <ctype.h> #include <errno.h> +#include <limits.h> static const char *usage = "\ PHP Options (available with -php7)\n\ @@ -64,6 +65,7 @@ static String *pragma_phpinfo; static String *pragma_version; static String *class_name = NULL; +static String *base_class = NULL; static String *destructor_action = NULL; static String *magic_set = NULL; static String *magic_get = NULL; @@ -102,7 +104,7 @@ static String *swig_wrapped_interface_ce() { static Hash *arginfo_used; /* Track non-class pointer types we need to to wrap */ -static Hash *zend_types = 0; +static Hash *raw_pointer_types = 0; static int shadow = 1; @@ -124,10 +126,10 @@ extern "C" { } static void SwigPHP_emit_pointer_type_registrations() { - if (!zend_types) + if (!raw_pointer_types) return; - Iterator ki = First(zend_types); + Iterator ki = First(raw_pointer_types); if (!ki.key) return; @@ -147,18 +149,18 @@ static void SwigPHP_emit_pointer_type_registrations() { Printf(s_wrappers, "/* Implement __toString equivalent, since that worked for the old-style resource wrapped pointers. */\n"); Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n"); Printf(s_wrappers, "static int swig_ptr_cast_object(zval *z, zval *retval, int type) {\n"); + Append(s_wrappers, "#elif PHP_MAJOR_VERSION > 8 || PHP_MINOR_VERSION >= 2\n"); + Printf(s_wrappers, "static ZEND_RESULT_CODE swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n"); Append(s_wrappers, "#else\n"); Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n"); Append(s_wrappers, "#endif\n"); Printf(s_wrappers, " if (type == IS_STRING) {\n"); - Printf(s_wrappers, " char buf[80];\n"); Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n"); Printf(s_wrappers, " swig_object_wrapper *obj = SWIG_Z_FETCH_OBJ_P(z);\n"); Append(s_wrappers, "#else\n"); Printf(s_wrappers, " swig_object_wrapper *obj = swig_php_fetch_object(zobj);\n"); Append(s_wrappers, "#endif\n"); - Printv(s_wrappers, " sprintf(buf, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject);\n", NIL); - Printf(s_wrappers, " ZVAL_STRING(retval, buf);\n"); + Printv(s_wrappers, " ZVAL_NEW_STR(retval, zend_strpprintf(0, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject));\n", NIL); Printf(s_wrappers, " return SUCCESS;\n"); Printf(s_wrappers, " }\n"); Printf(s_wrappers, " return FAILURE;\n"); @@ -187,10 +189,42 @@ static void SwigPHP_emit_pointer_type_registrations() { } } +static Hash *create_php_type_flags() { + Hash *h = NewHash(); + Setattr(h, "array", "MAY_BE_ARRAY"); + Setattr(h, "bool", "MAY_BE_BOOL"); + Setattr(h, "callable", "MAY_BE_CALLABLE"); + Setattr(h, "float", "MAY_BE_DOUBLE"); + Setattr(h, "int", "MAY_BE_LONG"); + Setattr(h, "iterable", "MAY_BE_ITERABLE"); + Setattr(h, "mixed", "MAY_BE_MIXED"); + Setattr(h, "null", "MAY_BE_NULL"); + Setattr(h, "object", "MAY_BE_OBJECT"); + Setattr(h, "resource", "MAY_BE_RESOURCE"); + Setattr(h, "string", "MAY_BE_STRING"); + Setattr(h, "void", "MAY_BE_VOID"); + return h; +} + +static Hash *php_type_flags = create_php_type_flags(); + +// php_class + ":" + php_method -> PHPTypes* +// ":" + php_function -> PHPTypes* +static Hash *all_phptypes = NewHash(); + +// php_class_name -> php_parent_class_name +static Hash *php_parent_class = NewHash(); + +// Track if a method is directed in a descendent class. +// php_class + ":" + php_method -> boolean (using SetFlag()/GetFlag()). +static Hash *has_directed_descendent = NewHash(); + +// Track required return type for parent class methods. +// php_class + ":" + php_method -> List of php types. +static Hash *parent_class_method_return_type = NewHash(); + // Class encapsulating the machinery to add PHP type declarations. class PHPTypes { - Hash *phptypes; - // List with an entry for each parameter and one for the return type. // // We assemble the types in here before emitting them so for an overloaded @@ -202,36 +236,42 @@ class PHPTypes { // the dispatch function. If NULL, no parameters are passed by reference. List *byref; -public: - PHPTypes() : phptypes(NewHash()), merged_types(NULL), byref(NULL) { - Setattr(phptypes, "array", "MAY_BE_ARRAY"); - Setattr(phptypes, "bool", "MAY_BE_BOOL"); - Setattr(phptypes, "callable", "MAY_BE_CALLABLE"); - Setattr(phptypes, "float", "MAY_BE_DOUBLE"); - Setattr(phptypes, "int", "MAY_BE_LONG"); - Setattr(phptypes, "iterable", "MAY_BE_ITERABLE"); - Setattr(phptypes, "mixed", "MAY_BE_MIXED"); - Setattr(phptypes, "null", "MAY_BE_NULL"); - Setattr(phptypes, "object", "MAY_BE_OBJECT"); - Setattr(phptypes, "resource", "MAY_BE_RESOURCE"); - Setattr(phptypes, "string", "MAY_BE_STRING"); - Setattr(phptypes, "void", "MAY_BE_VOID"); - } + // The id string used in the name of the arginfo for this object. + String *arginfo_id; - void reset() { - Delete(merged_types); - merged_types = NewList(); - Delete(byref); - byref = NULL; + // The feature:php:type value: 0, 1 or -1 for "compatibility". + int php_type_flag; + + // Does the node for this have directorNode set? + bool has_director_node; + + // Used to clamp the required number of parameters in the arginfo to be + // compatible with any parent class version of the method. + int num_required; + + int get_byref(int key) const { + return byref && key < Len(byref) && Getitem(byref, key) != None; } - // key is 0 for return type, or >= 1 for parameters numbered from 1 - void process_phptype(Node *n, int key, const String_or_char *attribute_name); + int size() const { + return std::max(Len(merged_types), Len(byref)); + } - String *get_phptype(int key, String *classtypes) { + String *get_phptype(int key, String *classtypes, List *more_return_types = NULL) { Clear(classtypes); + // We want to minimise the list of class types by not redundantly listing + // a class for which a super-class is also listed. This canonicalisation + // allows for more sharing of arginfo (which reduces module size), makes + // for a cleaner list if it's shown to the user, and also will speed up + // module load a bit. + Hash *classes = NewHash(); DOH *types = Getitem(merged_types, key); String *result = NewStringEmpty(); + if (more_return_types) { + if (types != None) { + merge_type_lists(types, more_return_types); + } + } if (types != None) { SortList(types, NULL); String *prev = NULL; @@ -240,18 +280,41 @@ public: // Skip duplicates when merging. continue; } - String *c = Getattr(phptypes, i.item); + String *c = Getattr(php_type_flags, i.item); if (c) { if (Len(result) > 0) Append(result, "|"); Append(result, c); } else { - if (Len(classtypes) > 0) Append(classtypes, "|"); - Append(classtypes, prefix); - Append(classtypes, i.item); + SetFlag(classes, i.item); } prev = i.item; } } + + // Remove entries for which a super-class is also listed. + Iterator i = First(classes); + while (i.key) { + String *this_class = i.key; + // We must advance the iterator early so we don't delete the element it + // points to. + i = Next(i); + String *parent = this_class; + while ((parent = Getattr(php_parent_class, parent)) != NULL) { + if (GetFlag(classes, parent)) { + Delattr(classes, this_class); + break; + } + } + } + + List *sorted_classes = SortedKeys(classes, Strcmp); + for (i = First(sorted_classes); i.item; i = Next(i)) { + if (Len(classtypes) > 0) Append(classtypes, "|"); + Append(classtypes, prefix); + Append(classtypes, i.item); + } + Delete(sorted_classes); + // Make the mask 0 if there are only class names specified. if (Len(result) == 0) { Append(result, "0"); @@ -259,6 +322,53 @@ public: return result; } +public: + PHPTypes(Node *n) + : merged_types(NewList()), + byref(NULL), + num_required(INT_MAX) { + String *php_type_feature = Getattr(n, "feature:php:type"); + php_type_flag = 0; + if (php_type_feature != NULL) { + if (Equal(php_type_feature, "1")) { + php_type_flag = 1; + } else if (!Equal(php_type_feature, "0")) { + php_type_flag = -1; + } + } + arginfo_id = Copy(Getattr(n, "sym:name")); + has_director_node = (Getattr(n, "directorNode") != NULL); + } + + ~PHPTypes() { + Delete(merged_types); + Delete(byref); + } + + void adjust(int num_required_, bool php_constructor) { + num_required = std::min(num_required, num_required_); + if (php_constructor) { + // Don't add a return type declaration for a PHP __construct method + // (because there it has no return type as far as PHP is concerned). + php_type_flag = 0; + } + } + + String *get_arginfo_id() const { + return arginfo_id; + } + + // key is 0 for return type, or >= 1 for parameters numbered from 1 + List *process_phptype(Node *n, int key, const String_or_char *attribute_name); + + // Merge entries from o_merge_list into merge_list, skipping any entries + // already present. + // + // Both merge_list and o_merge_list should be in sorted order. + static void merge_type_lists(List *merge_list, List *o_merge_list); + + void merge_from(const PHPTypes* o); + void set_byref(int key) { if (!byref) { byref = NewList(); @@ -266,17 +376,132 @@ public: while (Len(byref) <= key) { Append(byref, None); } + // If any overload takes a particular parameter by reference then the + // dispatch function also needs to take that parameter by reference so + // we can just set unconditionally here. Setitem(byref, key, ""); // Just needs to be something != None. } - int get_byref(int key) const { - return byref && key < Len(byref) && Getitem(byref, key) != None; + void emit_arginfo(DOH *item, String *key) { + Setmark(item, 1); + char *colon_ptr = Strchr(key, ':'); + assert(colon_ptr); + int colon = colon_ptr - Char(key); + if (colon > 0 && Strcmp(colon_ptr + 1, "__construct") != 0) { + // See if there's a parent class which implements this method, and if so + // emit its arginfo and then merge its PHPTypes into ours as we need to + // be compatible with it (whether it is virtual or not). + String *this_class = NewStringWithSize(Char(key), colon); + String *parent = this_class; + while ((parent = Getattr(php_parent_class, parent)) != NULL) { + String *k = NewStringf("%s%s", parent, colon_ptr); + DOH *item = Getattr(all_phptypes, k); + if (item) { + PHPTypes *p = (PHPTypes*)Data(item); + if (!Getmark(item)) { + p->emit_arginfo(item, k); + } + merge_from(p); + Delete(k); + break; + } + Delete(k); + } + Delete(this_class); + } + + // We want to only emit each different arginfo once, as that reduces the + // size of both the generated source code and the compiled extension + // module. The parameters at this level are just named arg1, arg2, etc + // so the arginfo will be the same for any function with the same number + // of parameters and (if present) PHP type declarations for parameters and + // return type. + // + // We generate the arginfo we want (taking care to normalise, e.g. the + // lists of types are unique and in sorted order), then use the + // arginfo_used Hash to see if we've already generated it. + String *out_phptype = NULL; + String *out_phpclasses = NewStringEmpty(); + + // We provide a simple way to generate PHP return type declarations + // except for directed methods. The point of directors is to allow + // subclassing in the target language, and if the wrapped method has + // a return type declaration then an overriding method in user code + // needs to have a compatible declaration. + // + // The upshot of this is that enabling return type declarations for + // existing bindings would break compatibility with user code written + // for an older version. For parameters however the situation is + // different because if the parent class declares types for parameters + // a subclass overriding the function will be compatible whether it + // declares them or not. + // + // directorNode being present seems to indicate if this method or one + // it inherits from is directed, which is what we care about here. + // Using (!is_member_director(n)) would get it wrong for testcase + // director_frob. + if (php_type_flag && (php_type_flag > 0 || !has_director_node)) { + if (!GetFlag(has_directed_descendent, key)) { + out_phptype = get_phptype(0, out_phpclasses, Getattr(parent_class_method_return_type, key)); + } + } + + // ### in arginfo_code will be replaced with the id once that is known. + String *arginfo_code = NewStringEmpty(); + if (out_phptype) { + if (Len(out_phpclasses)) { + Replace(out_phpclasses, "\\", "\\\\", DOH_REPLACE_ANY); + Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s, %s)\n", num_required, out_phpclasses, out_phptype); + } else { + Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s)\n", num_required, out_phptype); + } + } else { + Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required); + } + + int phptypes_size = size(); + for (int param_count = 1; param_count < phptypes_size; ++param_count) { + String *phpclasses = NewStringEmpty(); + String *phptype = get_phptype(param_count, phpclasses); + + int byref = get_byref(param_count); + + // FIXME: Should we be doing byref for return value as well? + + if (phptype) { + if (Len(phpclasses)) { + // We need to double any backslashes (which are PHP namespace + // separators) in the PHP class names as they get turned into + // C strings by the ZEND_ARG_OBJ_TYPE_MASK macro. + Replace(phpclasses, "\\", "\\\\", DOH_REPLACE_ANY); + Printf(arginfo_code, " ZEND_ARG_OBJ_TYPE_MASK(%d,arg%d,%s,%s,NULL)\n", byref, param_count, phpclasses, phptype); + } else { + Printf(arginfo_code, " ZEND_ARG_TYPE_MASK(%d,arg%d,%s,NULL)\n", byref, param_count, phptype); + } + } else { + Printf(arginfo_code, " ZEND_ARG_INFO(%d,arg%d)\n", byref, param_count); + } + } + Printf(arginfo_code, "ZEND_END_ARG_INFO()\n"); + + String *arginfo_id_same = Getattr(arginfo_used, arginfo_code); + if (arginfo_id_same) { + Printf(s_arginfo, "#define swig_arginfo_%s swig_arginfo_%s\n", arginfo_id, arginfo_id_same); + } else { + // Not had this arginfo before. + Setattr(arginfo_used, arginfo_code, arginfo_id); + arginfo_code = Copy(arginfo_code); + Replace(arginfo_code, "###", arginfo_id, DOH_REPLACE_FIRST); + Append(s_arginfo, arginfo_code); + } + Delete(arginfo_code); + arginfo_code = NULL; } }; -class PHP : public Language { - PHPTypes phptypes; +static PHPTypes *phptypes = NULL; +class PHP : public Language { public: PHP() { director_language = 1; @@ -342,7 +567,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewStringEmpty(); @@ -366,7 +591,7 @@ public: f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -384,7 +609,34 @@ public: Swig_banner(f_begin); - Printf(f_runtime, "\n\n#ifndef SWIGPHP\n#define SWIGPHP\n#endif\n\n"); + // We need to include php.h before string.h gets included, at least with + // PHP 8.2. Otherwise string.h is included without _GNU_SOURCE being + // included and memrchr() doesn't get declared, and then inline code in + // the PHP headers defines _GNU_SOURCE, includes string.h (which is a + // no op thanks to the include gaurds), then tries to use memrchr() and + // fails. + // + // We also need to suppress -Wdeclaration-after-statement if enabled + // since with PHP 8.2 zend_operators.h contains inline code which triggers + // this warning and our testsuite uses with option and -Werror. I don't + // see a good way to only do this within our testsuite, but disabling + // it globally like this shouldn't be problematic. + Append(f_runtime, + "\n" + "#if defined __GNUC__ && !defined __cplusplus\n" + "# if __GNUC__ >= 4\n" + "# pragma GCC diagnostic push\n" + "# pragma GCC diagnostic ignored \"-Wdeclaration-after-statement\"\n" + "# endif\n" + "#endif\n" + "#include \"php.h\"\n" + "#if defined __GNUC__ && !defined __cplusplus\n" + "# if __GNUC__ >= 4\n" + "# pragma GCC diagnostic pop\n" + "# endif\n" + "#endif\n\n"); + + Printf(f_runtime, "#ifndef SWIGPHP\n#define SWIGPHP\n#endif\n\n"); if (directorsEnabled()) { Printf(f_runtime, "#define SWIG_DIRECTORS\n"); @@ -438,7 +690,7 @@ public: f_h = NewFile(filen, "w", SWIG_output_files()); if (!f_h) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Swig_banner(f_h); @@ -472,6 +724,21 @@ public: /* Emit all of the code */ Language::top(n); + /* Emit all the arginfo. We sort the keys so the output order doesn't depend on + * hashkey order. + */ + { + List *sorted_keys = SortedKeys(all_phptypes, Strcmp); + for (Iterator k = First(sorted_keys); k.item; k = Next(k)) { + DOH *val = Getattr(all_phptypes, k.item); + if (!Getmark(val)) { + PHPTypes *p = (PHPTypes*)Data(val); + p->emit_arginfo(val, k.item); + } + } + Delete(sorted_keys); + } + SwigPHP_emit_pointer_type_registrations(); Dump(s_creation, s_header); Delete(s_creation); @@ -651,7 +918,7 @@ public: File *f_phpcode = NewFile(php_filename, "w", SWIG_output_files()); if (!f_phpcode) { FileErrorDisplay(php_filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printf(f_phpcode, "<?php\n\n"); @@ -675,13 +942,13 @@ public: void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes = NULL) { // This is for the single main zend_function_entry record ParmList *l = Getattr(n, "parms"); - if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) { + if (cname && !Equal(Getattr(n, "storage"), "friend")) { Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname); if (wrapperType != staticmemberfn && wrapperType != staticmembervar && !Equal(fname, "__construct")) { // Skip the first entry in the parameter list which is the this pointer. - l = Getattr(l, "tmap:in:next"); + if (l) l = Getattr(l, "tmap:in:next"); // FIXME: does this throw the phptype key value off? } } else { @@ -692,146 +959,31 @@ public: } } - int num_required = emit_num_required(l); - - // We want to only emit each different arginfo once, as that reduces the - // size of both the generated source code and the compiled extension - // module. The parameters at this level are just named arg1, arg2, etc - // so the arginfo will be the same for any function with the same number - // of parameters and (if present) PHP type declarations for parameters and - // return type. - // - // We generate the arginfo we want (taking care to normalise, e.g. the - // lists of types are unique and in sorted order), then use the - // arginfo_used Hash to see if we've already generated it. - - // Don't add a return type declaration for a constructor (because there - // is no return type as far as PHP is concerned). - String *out_phptype = NULL; - String *out_phpclasses = NewStringEmpty(); - if (!Equal(fname, "__construct")) { - String *php_type_flag = GetFlagAttr(n, "feature:php:type"); - if (Equal(php_type_flag, "1") || - (php_type_flag && !Getattr(n, "directorNode"))) { - // We provide a simple way to generate PHP return type declarations - // except for directed methods. The point of directors is to allow - // subclassing in the target language, and if the wrapped method has - // a return type declaration then an overriding method in user code - // needs to have a compatible declaration. - // - // The upshot of this is that enabling return type declarations for - // existing bindings would break compatibility with user code written - // for an older version. For parameters however the situation is - // different because if the parent class declares types for parameters - // a subclass overriding the function will be compatible whether it - // declares them or not. - // - // directorNode being present seems to indicate if this method or one - // it inherits from is directed, which is what we care about here. - // Using (!is_member_director(n)) would get it wrong for testcase - // director_frob. - out_phptype = phptypes.get_phptype(0, out_phpclasses); - } - } - - // ### in arginfo_code will be replaced with the id once that is known. - String *arginfo_code = NewStringEmpty(); - if (out_phptype) { - if (Len(out_phpclasses)) { - Replace(out_phpclasses, "\\", "\\\\", DOH_REPLACE_ANY); - Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s, %s)\n", num_required, out_phpclasses, out_phptype); - } else { - Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s)\n", num_required, out_phptype); - } - } else { - Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required); - } - - if (Getattr(n, "defaultargs")) { - // Include parameters with default values in the arginfo. - l = Getattr(Getattr(n, "defaultargs"), "parms"); - } - int param_count = 0; - for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) { - String *tmap_in_numinputs = Getattr(p, "tmap:in:numinputs"); - // tmap:in:numinputs is unset for varargs, which we don't count here. - if (!tmap_in_numinputs || Equal(tmap_in_numinputs, "0")) { - /* Ignored parameter */ - continue; - } - - ++param_count; - - String *phpclasses = NewStringEmpty(); - String *phptype = NULL; - if (GetFlag(n, "feature:php:type")) { - phptype = phptypes.get_phptype(param_count, phpclasses); - } - - int byref; - if (!dispatch) { - byref = GetFlag(p, "tmap:in:byref"); - if (byref) phptypes.set_byref(param_count); - } else { - // If any overload takes a particular parameter by reference then the - // dispatch function also needs to take that parameter by reference. - byref = phptypes.get_byref(param_count); - } - - // FIXME: Should we be doing byref for return value as well? - - if (phptype) { - if (Len(phpclasses)) { - // We need to double any backslashes (which are PHP namespace - // separators) in the PHP class names as they get turned into - // C strings by the ZEND_ARG_OBJ_TYPE_MASK macro. - Replace(phpclasses, "\\", "\\\\", DOH_REPLACE_ANY); - Printf(arginfo_code, " ZEND_ARG_OBJ_TYPE_MASK(%d,arg%d,%s,%s,NULL)\n", byref, param_count, phpclasses, phptype); - } else { - Printf(arginfo_code, " ZEND_ARG_TYPE_MASK(%d,arg%d,%s,NULL)\n", byref, param_count, phptype); - } - } else { - Printf(arginfo_code, " ZEND_ARG_INFO(%d,arg%d)\n", byref, param_count); - } - } - Printf(arginfo_code, "ZEND_END_ARG_INFO()\n"); - - String *arginfo_id_new = Getattr(n, "sym:name"); - String *arginfo_id = Getattr(arginfo_used, arginfo_code); - if (arginfo_id) { - Printf(s_arginfo, "#define swig_arginfo_%s swig_arginfo_%s\n", arginfo_id_new, arginfo_id); - } else { - // Not had this arginfo before. - Setattr(arginfo_used, arginfo_code, arginfo_id_new); - arginfo_code = Copy(arginfo_code); - Replace(arginfo_code, "###", arginfo_id_new, DOH_REPLACE_FIRST); - Append(s_arginfo, arginfo_code); - } - Delete(arginfo_code); - arginfo_code = NULL; + phptypes->adjust(emit_num_required(l), Equal(fname, "__construct")); + String *arginfo_id = phptypes->get_arginfo_id(); String *s = cs_entry; if (!s) s = s_entry; - if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) { - Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id_new, modes); + if (cname && !Equal(Getattr(n, "storage"), "friend")) { + Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes); } else { if (dispatch) { if (wrap_nonclass_global) { - Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_id_new); + Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_id); } if (wrap_nonclass_fake_class) { (void)fake_class_name(); - Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_id_new); + Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_id); } } else { if (wrap_nonclass_global) { - Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_id_new); + Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_id); } if (wrap_nonclass_fake_class) { String *fake_class = fake_class_name(); - Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_id_new); + Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_id); } } } @@ -856,8 +1008,8 @@ public: bool constructorRenameOverload = false; if (constructor) { - // Renamed constructor - turn into static factory method - if (Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) != 0) { + if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) { + // Renamed constructor - turn into static factory method constructorRenameOverload = true; wname = Copy(Getattr(n, "constructorHandler:sym:name")); } else { @@ -882,7 +1034,7 @@ public: create_command(class_name, wname, n, true, modes); - if (class_name && Cmp(Getattr(n, "storage"), "friend") != 0) { + if (class_name && !Equal(Getattr(n, "storage"), "friend")) { Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL); } else { Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL); @@ -924,9 +1076,10 @@ public: return n && Getattr(n, "classtype") != NULL; } - void generate_magic_property_methods(Node *class_node, String *base_class) { - if (Equal(base_class, "Exception") || !is_class_wrapped(base_class)) { - base_class = NULL; + void generate_magic_property_methods(Node *class_node) { + String *swig_base = base_class; + if (Equal(swig_base, "Exception") || !is_class_wrapped(swig_base)) { + swig_base = NULL; } static bool generated_magic_arginfo = false; @@ -976,12 +1129,12 @@ public: " if (director) director->swig_disown();\n", "}\n", NIL); } - Printf(f->code, "} else {\n"); - if (base_class) { - Printf(f->code, "PHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class); - } else { - Printf(f->code, "add_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n}\n"); + if (swig_base) { + Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base); + } else if (Getattr(class_node, "feature:php:allowdynamicproperties")) { + Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n"); } + Printf(f->code, "}\n"); Printf(f->code, "fail:\n"); Printf(f->code, "return;\n"); @@ -1009,8 +1162,8 @@ public: Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n"); Printf(f->code, "if(arg->newobject) {\nRETVAL_LONG(1);\n}\nelse {\nRETVAL_LONG(0);\n}\n}\n\n"); Printf(f->code, "else {\n"); - if (base_class) { - Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class); + if (swig_base) { + Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base); } else { // __get is only called if the property isn't set on the zend_object. Printf(f->code, "RETVAL_NULL();\n}\n"); @@ -1042,8 +1195,8 @@ public: Append(f->code, magic_isset); } Printf(f->code, "else {\n"); - if (base_class) { - Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class); + if (swig_base) { + Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base); } else { // __isset is only called if the property isn't set on the zend_object. Printf(f->code, "RETVAL_FALSE;\n}\n"); @@ -1142,14 +1295,13 @@ public: return SWIG_ERROR; } - if (!Getattr(n, "sym:previousSibling")) { - // First function of an overloaded group or a function which isn't part - // of a group so reset the phptype information. - phptypes.reset(); - } - if (constructor) { - wname = NewString("__construct"); + if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) { + // Renamed constructor - turn into static factory method + wname = Copy(Getattr(n, "constructorHandler:sym:name")); + } else { + wname = NewString("__construct"); + } } else if (wrapperType == membervar) { wname = Copy(Getattr(n, "membervariableHandler:sym:name")); if (is_setter_method(n)) { @@ -1172,7 +1324,7 @@ public: if (is_getter_method(n)) { // This is to overcome types that can't be set and hence no setter. - if (Cmp(Getattr(n, "feature:immutable"), "1") != 0) + if (!Equal(Getattr(n, "feature:immutable"), "1")) static_getter = true; } } else if (wrapperType == staticmemberfn) { @@ -1198,6 +1350,28 @@ public: return SWIG_OK; } + if (!static_getter) { + // Create or find existing PHPTypes. + phptypes = NULL; + + String *key; + if (class_name && !Equal(Getattr(n, "storage"), "friend")) { + key = NewStringf("%s:%s", class_name, wname); + } else { + key = NewStringf(":%s", wname); + } + + PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key); + if (p) { + // We already have an entry so use it. + phptypes = p; + Delete(key); + } else { + phptypes = new PHPTypes(n); + SetVoid(all_phptypes, key, phptypes); + } + } + f = NewWrapper(); if (static_getter) { @@ -1209,7 +1383,7 @@ public: if (!overloaded) { if (!static_getter) { - if (class_name && Cmp(Getattr(n, "storage"), "friend") != 0) { + if (class_name && !Equal(Getattr(n, "storage"), "friend")) { Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL); } else { if (wrap_nonclass_global) { @@ -1314,7 +1488,8 @@ public: continue; } - phptypes.process_phptype(p, i + 1, "tmap:in:phptype"); + phptypes->process_phptype(p, i + 1, "tmap:in:phptype"); + if (GetFlag(p, "tmap:in:byref")) phptypes->set_byref(i + 1); String *source = NewStringf("args[%d]", i); Replaceall(tm, "$input", source); @@ -1400,7 +1575,33 @@ public: } emit_return_variable(n, d, f); - phptypes.process_phptype(n, 0, "tmap:out:phptype"); + List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype"); + + if (class_name && !Equal(Getattr(n, "storage"), "friend")) { + if (is_member_director(n)) { + String *parent = class_name; + while ((parent = Getattr(php_parent_class, parent)) != NULL) { + // Mark this method name as having no return type declaration for all + // classes we're derived from. + SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname)); + } + } else if (return_types) { + String *parent = class_name; + while ((parent = Getattr(php_parent_class, parent)) != NULL) { + String *key = NewStringf("%s:%s", parent, wname); + // The parent class method needs to have a superset of the possible + // return types of methods with the same name in subclasses. + List *v = Getattr(parent_class_method_return_type, key); + if (!v) { + // New entry. + Setattr(parent_class_method_return_type, key, Copy(return_types)); + } else { + // Update existing entry. + PHPTypes::merge_type_lists(v, return_types); + } + } + } + } if (outarg) { Printv(f->code, outarg, NIL); @@ -1451,7 +1652,7 @@ public: dispatchFunction(n, constructor); } } else { - if (!static_getter) { + if (!static_setter) { create_command(class_name, wname, n, false, modes); } } @@ -1573,11 +1774,6 @@ public: * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { - if (!Getattr(n, "feature:onlychildren")) { - String *symname = Getattr(n, "sym:name"); - Setattr(n, "php:proxy", symname); - } - return Language::classDeclaration(n); } @@ -1587,9 +1783,9 @@ public: virtual int classHandler(Node *n) { String *symname = Getattr(n, "sym:name"); - String *base_class = NULL; class_name = symname; + base_class = NULL; destructor_action = NULL; Printf(all_cs_entry, "static const zend_function_entry class_%s_functions[] = {\n", class_name); @@ -1644,6 +1840,7 @@ public: Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name); } else if (is_class_wrapped(base_class)) { Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class); + Setattr(php_parent_class, class_name, base_class); } else { Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name); } @@ -1651,6 +1848,15 @@ public: if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) { Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name); } + if (Getattr(n, "feature:php:allowdynamicproperties")) { + Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n"); + Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name); + Append(s_oinit, "#endif\n"); + } else { + Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n"); + Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name); + Append(s_oinit, "#endif\n"); + } String *swig_wrapped = swig_wrapped_interface_ce(); Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL); @@ -1800,10 +2006,11 @@ public: Printf(s_oinit, "#endif\n"); Printf(s_oinit, "\n"); - generate_magic_property_methods(n, base_class); + generate_magic_property_methods(n); Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); class_name = NULL; + base_class = NULL; return SWIG_OK; } @@ -2125,10 +2332,6 @@ public: Parm *p; - int outputs = 0; - if (!is_void) - outputs++; - /* build argument list and type conversion string */ idx = 0; p = l; @@ -2138,9 +2341,6 @@ public: continue; } - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - String *pname = Getattr(p, "name"); String *ptype = Getattr(p, "type"); @@ -2206,11 +2406,13 @@ public: if (tm) tm = Copy(tm); } - if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - Replaceall(tm, "$error", "EG(exception)"); - Printv(w->code, Str(tm), "\n", NIL); + if (!tm || Len(tm) == 0 || Equal(tm, "1")) { + // Skip marshalling the return value as there isn't one. + tm = NewString("if ($error) SWIG_fail;"); } - Append(w->code, "}\n"); + + Replaceall(tm, "$error", "EG(exception)"); + Printv(w->code, Str(tm), "\n}\n{\n", NIL); Delete(tm); /* marshal return value from PHP to C/C++ type */ @@ -2258,6 +2460,8 @@ public: } } + Append(w->code, "}\n"); + Delete(cleanup); Delete(outarg); } @@ -2318,7 +2522,7 @@ public: static PHP *maininstance = 0; -void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) { +List *PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) { while (Len(merged_types) <= key) { Append(merged_types, NewList()); @@ -2332,11 +2536,11 @@ void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute // declaration for this parameter/return value (you can't store NULL as a // value in a DOH List). Setitem(merged_types, key, None); - return; + return NULL; } DOH *merge_list = Getitem(merged_types, key); - if (merge_list == None) return; + if (merge_list == None) return NULL; List *types = Split(phptype, '|', -1); String *first_type = Getitem(types, 0); @@ -2381,9 +2585,9 @@ void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute // fails at runtime and the error isn't very helpful). We could // check the condition // - // zend_types && Getattr(zend_types, SwigType_manglestr(type)) + // raw_pointer_types && Getattr(raw_pointer_types, SwigType_manglestr(type)) // - // except that zend_types may not have been fully filled in when + // except that raw_pointer_types may not have been fully filled in when // we are called. Append(merge_list, NewStringf("SWIG\\%s", SwigType_manglestr(type))); } @@ -2392,6 +2596,67 @@ void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute } prev = i.item; } + SortList(merge_list, NULL); + return merge_list; +} + +void PHPTypes::merge_type_lists(List *merge_list, List *o_merge_list) { + int i = 0, j = 0; + while (j < Len(o_merge_list)) { + String *candidate = Getitem(o_merge_list, j); + while (i < Len(merge_list)) { + int cmp = Cmp(Getitem(merge_list, i), candidate); + if (cmp == 0) + goto handled; + if (cmp > 0) + break; + ++i; + } + Insert(merge_list, i, candidate); + ++i; +handled: + ++j; + } +} + +void PHPTypes::merge_from(const PHPTypes* o) { + num_required = std::min(num_required, o->num_required); + + if (o->byref) { + if (byref == NULL) { + byref = Copy(o->byref); + } else { + int len = std::min(Len(byref), Len(o->byref)); + // Start at 1 because we only want to merge parameter types, and key 0 is + // the return type. + for (int key = 1; key < len; ++key) { + if (Getitem(byref, key) == None && + Getitem(o->byref, key) != None) { + Setitem(byref, key, ""); + } + } + for (int key = len; key < Len(o->byref); ++key) { + Append(byref, Getitem(o->byref, key)); + } + } + } + + int len = std::min(Len(merged_types), Len(o->merged_types)); + for (int key = 0; key < len; ++key) { + DOH *merge_list = Getitem(merged_types, key); + // None trumps anything else in the merge. + if (merge_list == None) continue; + DOH *o_merge_list = Getitem(o->merged_types, key); + if (o_merge_list == None) { + Setitem(merged_types, key, None); + continue; + } + merge_type_lists(merge_list, o_merge_list); + } + // Copy over any additional entries. + for (int key = len; key < Len(o->merged_types); ++key) { + Append(merged_types, Copy(Getitem(o->merged_types, key))); + } } // Collect non-class pointer types from the type table so we can set up PHP @@ -2402,10 +2667,10 @@ extern "C" { static void typetrace(const SwigType *ty, String *mangled, String *clientdata) { if (maininstance->classLookup(ty) == NULL) { // a non-class pointer - if (!zend_types) { - zend_types = NewHash(); + if (!raw_pointer_types) { + raw_pointer_types = NewHash(); } - Setattr(zend_types, mangled, mangled); + Setattr(raw_pointer_types, mangled, mangled); } if (r_prevtracefunc) (*r_prevtracefunc) (ty, mangled, clientdata); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 7bfe9fc0e..6a1c0a0a2 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * python.cxx * @@ -12,13 +12,12 @@ * ----------------------------------------------------------------------------- */ #include "swigmod.h" -#include <limits.h> #include "cparse.h" +#include <limits.h> #include <ctype.h> #include <errno.h> -#include "pydoc.h" - #include <stdint.h> +#include "pydoc.h" #define PYSHADOW_MEMBER 0x2 #define WARN_PYTHON_MULTIPLE_INH 405 @@ -69,8 +68,6 @@ static int no_header_file = 0; static int max_bases = 0; static int builtin_bases_needed = 0; -static int py3 = 0; - /* C++ Support + Shadow Classes */ static int have_constructor = 0; @@ -93,6 +90,7 @@ static int castmode = 0; static int extranative = 0; static int nortti = 0; static int relativeimport = 0; +static int flat_static_method = 0; /* flags for the make_autodoc function */ namespace { @@ -118,6 +116,7 @@ Python Options (available with -python)\n\ -doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes\n\ -extranative - Return extra native wrappers for C++ std containers wherever possible\n\ -fastproxy - Use fast proxy mechanism for member methods\n\ + -flatstaticmethod - Generate additional flattened Python methods for C++ static methods\n\ -globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\ -interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\ -keyword - Use keyword arguments\n"; @@ -129,7 +128,6 @@ static const char *usage3 = "\ -nortti - Disable the use of the native C++ RTTI with directors\n\ -nothreads - Disable thread support for the entire interface\n\ -olddefs - Keep the old method definitions when using -fastproxy\n\ - -py3 - Generate code with Python 3 specific features and syntax\n\ -relativeimport - Use relative Python imports\n\ -threads - Add thread support for all the interface\n\ -O - Enable the following optimization options:\n\ @@ -373,6 +371,9 @@ public: } else if (strcmp(argv[i], "-extranative") == 0) { extranative = 1; Swig_mark_arg(i); + } else if (strcmp(argv[i], "-flatstaticmethod") == 0) { + flat_static_method = 1; + Swig_mark_arg(i); } else if (strcmp(argv[i], "-noh") == 0) { no_header_file = 1; Swig_mark_arg(i); @@ -391,10 +392,6 @@ public: fputs(usage1, stdout); fputs(usage2, stdout); fputs(usage3, stdout); - } else if (strcmp(argv[i], "-py3") == 0) { - py3 = 1; - Preprocessor_define("SWIGPYTHON_PY3", 0); - Swig_mark_arg(i); } else if (strcmp(argv[i], "-builtin") == 0) { builtin = 1; Preprocessor_define("SWIGPYTHON_BUILTIN", 0); @@ -410,7 +407,10 @@ public: strcmp(argv[i], "-modernargs") == 0 || strcmp(argv[i], "-noproxydel") == 0 || strcmp(argv[i], "-safecstrings") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); + Printf(stderr, "Deprecated command line option: %s. Ignored, this option is now always on.\n", argv[i]); + Swig_mark_arg(i); + } else if (strcmp(argv[i], "-py3") == 0) { + Printf(stderr, "Deprecated command line option: %s. Ignored, this option is no longer supported.\n", argv[i]); Swig_mark_arg(i); } else if (strcmp(argv[i], "-aliasobj0") == 0 || strcmp(argv[i], "-buildnone") == 0 || @@ -438,9 +438,9 @@ public: strcmp(argv[i], "-oldrepr") == 0 || strcmp(argv[i], "-outputtuple") == 0 || strcmp(argv[i], "-proxydel") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); + Printf(stderr, "Deprecated command line option: %s. This option is no longer available.\n", argv[i]); Swig_mark_arg(i); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -448,7 +448,7 @@ public: if (builtin && !shadow) { Printf(stderr, "Incompatible options -builtin and -noproxy specified.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (fastproxy) { @@ -507,22 +507,22 @@ public: } if (Getattr(options, "nocastmode")) { Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (Getattr(options, "extranative")) { extranative = 1; } if (Getattr(options, "noextranative")) { Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (Getattr(options, "outputtuple")) { Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (Getattr(options, "nooutputtuple")) { Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } mod_docstring = Getattr(options, "docstring"); package = Getattr(options, "package"); @@ -541,7 +541,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); @@ -565,7 +565,7 @@ public: f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } else { f_runtime_h = f_runtime; @@ -670,7 +670,7 @@ public: Insert(module, 0, "_"); if ((f_shadow_py = NewFile(filen, "w", SWIG_output_files())) == 0) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(filen); filen = NULL; @@ -711,9 +711,11 @@ public: Printv(default_import_code, tab4, "from ", module, " import *\n", NULL); } - /* Need builtins to qualify names like Exception that might also be - defined in this module (try both Python 3 and Python 2 names) */ - Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL); + if (!builtin) { + /* Need builtins to qualify names like Exception that might also be + defined in this module (try both Python 3 and Python 2 names) */ + Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL); + } if (!builtin && fastproxy) { Printf(f_shadow, "\n"); @@ -721,58 +723,54 @@ public: Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module); } - Printv(f_shadow, "\n", - "def _swig_repr(self):\n", - tab4, "try:\n", - tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n", - tab4, "except __builtin__.Exception:\n", - tab4, tab4, "strthis = \"\"\n", - tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL); - - Printv(f_shadow, "\n", - "def _swig_setattr_nondynamic_instance_variable(set):\n", - tab4, "def set_instance_attr(self, name, value):\n", -#ifdef USE_THISOWN - tab4, tab4, "if name in (\"this\", \"thisown\"):\n", - tab4, tab4, tab4, "set(self, name, value)\n", -#else - tab4, tab4, "if name == \"thisown\":\n", - tab4, tab4, tab4, "self.this.own(value)\n", - tab4, tab4, "elif name == \"this\":\n", - tab4, tab4, tab4, "set(self, name, value)\n", -#endif - tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n", - tab4, tab4, tab4, "set(self, name, value)\n", - tab4, tab4, "else:\n", - tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n", - tab4, "return set_instance_attr\n\n", NIL); - - Printv(f_shadow, "\n", - "def _swig_setattr_nondynamic_class_variable(set):\n", - tab4, "def set_class_attr(cls, name, value):\n", - tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n", - tab4, tab4, tab4, "set(cls, name, value)\n", - tab4, tab4, "else:\n", - tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n", - tab4, "return set_class_attr\n\n", NIL); - - Printv(f_shadow, "\n", - "def _swig_add_metaclass(metaclass):\n", - tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n", - tab4, "def wrapper(cls):\n", - tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n", - tab4, "return wrapper\n\n", NIL); - - Printv(f_shadow, "\n", - "class _SwigNonDynamicMeta(type):\n", - tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n", - tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n", - "\n", NIL); - - Printv(f_shadow, "\n", NIL); - - if (directorsEnabled()) { - Printv(f_shadow, "import weakref\n\n", NIL); + if (!builtin) { + Printv(f_shadow, "\n", + "def _swig_repr(self):\n", + tab4, "try:\n", + tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n", + tab4, "except __builtin__.Exception:\n", + tab4, tab4, "strthis = \"\"\n", + tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL); + + Printv(f_shadow, "\n", + "def _swig_setattr_nondynamic_instance_variable(set):\n", + tab4, "def set_instance_attr(self, name, value):\n", + tab4, tab4, "if name == \"this\":\n", + tab4, tab4, tab4, "set(self, name, value)\n", + tab4, tab4, "elif name == \"thisown\":\n", + tab4, tab4, tab4, "self.this.own(value)\n", + tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n", + tab4, tab4, tab4, "set(self, name, value)\n", + tab4, tab4, "else:\n", + tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n", + tab4, "return set_instance_attr\n\n", NIL); + + Printv(f_shadow, "\n", + "def _swig_setattr_nondynamic_class_variable(set):\n", + tab4, "def set_class_attr(cls, name, value):\n", + tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n", + tab4, tab4, tab4, "set(cls, name, value)\n", + tab4, tab4, "else:\n", + tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n", + tab4, "return set_class_attr\n\n", NIL); + + Printv(f_shadow, "\n", + "def _swig_add_metaclass(metaclass):\n", + tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n", + tab4, "def wrapper(cls):\n", + tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n", + tab4, "return wrapper\n\n", NIL); + + Printv(f_shadow, "\n", + "class _SwigNonDynamicMeta(type):\n", + tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n", + tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n", + "\n", NIL); + + Printv(f_shadow, "\n", NIL); + + if (directorsEnabled()) + Printv(f_shadow, "import weakref\n\n", NIL); } } // Include some information in the code @@ -819,7 +817,8 @@ public: Printf(f_wrappers, "%s\n", methods); Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n"); Append(methods_proxydocs, "};\n"); - Printf(f_wrappers, "%s\n", methods_proxydocs); + if ((fastproxy && !builtin) || have_fast_proxy_static_member_method_callback) + Printf(f_wrappers, "%s\n", methods_proxydocs); if (builtin) { Dump(f_builtins, f_wrappers); @@ -865,13 +864,6 @@ public: Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL); Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL); - if (py3) { - Printv(f_shadow_py, "if _swig_python_version_info < (3, 0):\n", NULL); - Printv(f_shadow_py, tab4, "raise RuntimeError(\"Python 3.x or later required\")\n\n", NULL); - } else { - Printv(f_shadow_py, "if _swig_python_version_info < (2, 7, 0):\n", NULL); - Printv(f_shadow_py, tab4, "raise RuntimeError(\"Python 2.7 or later required\")\n\n", NULL); - } if (Len(f_shadow_after_begin) > 0) Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL); @@ -883,8 +875,10 @@ public: Printv(f_shadow_py, default_import_code, NIL); } - Printv(f_shadow_py, "\n", f_shadow, "\n", NIL); - Printv(f_shadow_py, f_shadow_stubs, "\n", NIL); + if (Len(f_shadow) > 0) + Printv(f_shadow_py, "\n", f_shadow, "\n", NIL); + if (Len(f_shadow_stubs) > 0) + Printv(f_shadow_py, f_shadow_stubs, "\n", NIL); Delete(f_shadow_py); } @@ -1497,16 +1491,18 @@ public: /* ------------------------------------------------------------ * build_combined_docstring() * - * Build the full docstring which may be a combination of the - * explicit docstring and autodoc string or, if none of them - * is specified, obtained by translating Doxygen comment to - * Python. + * Build the full docstring: + * Use the docstring if there is one present otherwise + * use the Doxygen comment if there is one present. + * Ignore autodoc if there is a Doxygen comment, otherwise + * create the autodoc string and append to any docstring. * * Return new string to be deleted by caller (never NIL but * may be empty if there is no docstring). * ------------------------------------------------------------ */ String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) { + bool add_autodoc = true; String *docstr = Getattr(n, "feature:docstring"); if (docstr) { // Simplify the code below by just ignoring empty docstrings. @@ -1524,26 +1520,10 @@ public: } } - if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) { - String *autodoc = make_autodoc(n, ad_type, low_level); - if (autodoc && Len(autodoc) > 0) { - if (docstr) { - Append(autodoc, "\n"); - Append(autodoc, docstr); - } - - String *tmp = autodoc; - autodoc = docstr; - docstr = tmp; - } - - Delete(autodoc); - } - if (!docstr) { - if (doxygen) { + if (doxygen && doxygenTranslator->hasDocumentation(n)) { docstr = Getattr(n, "python:docstring"); - if (!docstr && doxygenTranslator->hasDocumentation(n)) { + if (!docstr) { docstr = doxygenTranslator->getDocumentation(n, 0); // Avoid rebuilding it again the next time: notice that we can't do @@ -1559,9 +1539,26 @@ public: // the cached object! docstr = Copy(docstr); } + add_autodoc = false; } } + if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) { + String *autodoc = make_autodoc(n, ad_type, low_level); + if (autodoc && Len(autodoc) > 0) { + if (docstr) { + Append(autodoc, "\n"); + Append(autodoc, docstr); + } + + String *tmp = autodoc; + autodoc = docstr; + docstr = tmp; + } + + Delete(autodoc); + } + if (!docstr) docstr = NewString(""); @@ -2395,6 +2392,23 @@ public: } /* ------------------------------------------------------------ + * variableAnnotation() + * + * Helper function for constructing a variable annotation + * ------------------------------------------------------------ */ + + String *variableAnnotation(Node *n) { + String *type = Getattr(n, "type"); + if (type) + type = SwigType_str(type, 0); + bool anno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false; + anno = GetFlag(n, "feature:python:annotations:novar") ? false : anno; + String *annotation = (type && anno) ? NewStringf(": \"%s\"", type) : NewString(""); + Delete(type); + return annotation; + } + + /* ------------------------------------------------------------ * emitFunctionShadowHelper() * * Refactoring some common code out of functionWrapper and @@ -2514,7 +2528,7 @@ public: /* ------------------------------------------------------------ * dispatchFunction() * ------------------------------------------------------------ */ - void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false) { + void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false, bool use_static_method = false) { /* Last node in overloaded chain */ bool add_self = builtin_self && (!builtin_ctor || director_class); @@ -2618,11 +2632,11 @@ public: Printv(f->code, "}\n", NIL); Wrapper_print(f, f_wrappers); Node *p = Getattr(n, "sym:previousSibling"); - if (!builtin_self) + if (!builtin_self && (use_static_method || !builtin)) add_method(symname, wname, 0, p); /* Create a shadow for this function (if enabled and not in a member function) */ - if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) { + if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) { emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0); } DelWrapper(f); @@ -3287,18 +3301,20 @@ public: Wrapper_print(f, f_wrappers); } + bool use_static_method = flat_static_method || !Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage"); /* Now register the function with the interpreter. */ if (!Getattr(n, "sym:overloaded")) { - if (!builtin_self) + if (!builtin_self && (use_static_method || !builtin)) add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments); /* Create a shadow for this function (if enabled and not in a member function) */ - if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) { + if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) { emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs); } + } else { if (!Getattr(n, "sym:nextSibling")) { - dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class); + dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method); } } @@ -3454,7 +3470,7 @@ public: if (builtin) Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name); have_globals = 1; - if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) { + if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) { Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name); } } @@ -3612,7 +3628,7 @@ public: if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { Replaceall(tm, "$value", value); - if (needs_swigconstant(n) && !builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER)) && (!in_class || !Getattr(n, "feature:python:callback"))) { + if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) { // Generate `*_swigconstant()` method which registers the new constant. // // *_swigconstant methods are required for constants of class type. @@ -3650,7 +3666,7 @@ public: return SWIG_NOWRAP; } - if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) { + if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) { String *f_s; if (!in_class) { f_s = f_shadow; @@ -3885,11 +3901,7 @@ public: String *symname = Getattr(n, "sym:name"); String *mrename = Swig_name_disown(NSPACE_TODO, symname); //Getattr(n, "name")); Printv(f_shadow, tab4, "def __disown__(self):\n", NIL); -#ifdef USE_THISOWN - Printv(f_shadow, tab8, "self.thisown = 0\n", NIL); -#else Printv(f_shadow, tab8, "self.this.disown()\n", NIL); -#endif Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL); Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL); Delete(mrename); @@ -4059,14 +4071,16 @@ public: Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n"); Printf(f, " Py_XINCREF(other);\n"); } - Iterator rich_iter = First(richcompare); + List *richcompare_list = SortedKeys(richcompare, 0); + Iterator rich_iter = First(richcompare_list); if (rich_iter.item) { Printf(f, " switch (op) {\n"); for (; rich_iter.item; rich_iter = Next(rich_iter)) - Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.key, rich_iter.item, funpack ? "other" : "tuple"); + Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple"); Printv(f, " default : break;\n", NIL); Printf(f, " }\n"); } + Delete(richcompare_list); Printv(f, " if (!result) {\n", NIL); Printv(f, " if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL); Printv(f, " result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL); @@ -4130,7 +4144,11 @@ public: printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize"); printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize"); printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor"); + Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL); printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc"); + Printv(f, "#else\n", NIL); + printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t"); + Printv(f, "#endif\n", NIL); printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc"); printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); @@ -4214,6 +4232,9 @@ public: printSlot(f, getSlot(n, "feature:python:am_await"), "am_await", "unaryfunc"); printSlot(f, getSlot(n, "feature:python:am_aiter"), "am_aiter", "unaryfunc"); printSlot(f, getSlot(n, "feature:python:am_anext"), "am_anext", "unaryfunc"); + Printv(f, "# if PY_VERSION_HEX >= 0x030a0000\n", NIL); + printSlot(f, getSlot(n, "feature:python:am_send"), "am_send", "sendfunc"); + Printv(f, "# endif\n", NIL); Printf(f, " },\n"); Printv(f, "#endif\n", NIL); @@ -4327,9 +4348,20 @@ public: printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys"); Printv(f, "#endif\n", NIL); + // PyObject *ht_module; Printv(f, "#if PY_VERSION_HEX >= 0x03090000\n", NIL); printSlot(f, getSlot(n, "feature:python:ht_module"), "ht_module", "PyObject *"); Printv(f, "#endif\n", NIL); + + // char *_ht_tpname; + Printv(f, "#if PY_VERSION_HEX >= 0x030b0000\n", NIL); + printSlot(f, getSlot(n, "feature:python:_ht_tpname"), "_ht_tpname", "char *"); + + // struct _specialization_cache _spec_cache; + Printf(f, " {\n"); + printSlot(f, getSlot(n, "feature:python:getitem"), "getitem", "PyObject *"); + Printf(f, " }\n"); + Printv(f, "#endif\n", NIL); Printf(f, "};\n\n"); String *clientdata = NewString(""); @@ -4454,10 +4486,9 @@ public: /* dealing with abstract base class */ String *abcs = Getattr(n, "feature:python:abc"); - if (py3 && abcs) { - if (Len(base_class)) { + if (abcs) { + if (Len(base_class) > 0) Printv(base_class, ", ", NIL); - } Printv(base_class, abcs, NIL); } @@ -4473,10 +4504,8 @@ public: Delete(rname); } } else { - if (!py3) { - if (GetFlag(n, "feature:python:nondynamic")) - Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL); - } + if (GetFlag(n, "feature:python:nondynamic")) + Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL); Printv(f_shadow, "class ", class_name, NIL); if (Len(base_class)) { @@ -4486,9 +4515,11 @@ public: Printf(f_shadow, "(Exception)"); } else { Printf(f_shadow, "(object"); - if (py3 && GetFlag(n, "feature:python:nondynamic")) { + /* Replace @_swig_add_metaclass above with below when support for python 2.7 is dropped + if (GetFlag(n, "feature:python:nondynamic")) { Printf(f_shadow, ", metaclass=_SwigNonDynamicMeta"); } + */ Printf(f_shadow, ")"); } } @@ -4603,7 +4634,8 @@ public: } shadow_indent = 0; - Printf(f_shadow_file, "%s\n", f_shadow_stubs); + if (Len(f_shadow_stubs) > 0) + Printf(f_shadow_file, "%s\n", f_shadow_stubs); Clear(f_shadow_stubs); } @@ -4949,9 +4981,6 @@ public: if (have_pythonprepend(n)) Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL); -#ifdef USE_THISOWN - Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL); -#endif if (have_pythonappend(n)) Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); Printv(f_shadow_stubs, tab4, "return val\n", NIL); @@ -5007,12 +5036,6 @@ public: Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL); if (have_pythonprepend(n)) Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); -#ifdef USE_THISOWN - Printv(f_shadow, tab8, "try:\n", NIL); - Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL); - Printv(f_shadow, tab8, "except __builtin__.Exception: pass\n", NIL); -#else -#endif if (have_pythonappend(n)) Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); Printv(f_shadow, tab8, "pass\n", NIL); @@ -5040,12 +5063,17 @@ public: String *setname = Swig_name_set(NSPACE_TODO, mname); String *getname = Swig_name_get(NSPACE_TODO, mname); int assignable = is_assignable(n); - Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL); + String *variable_annotation = variableAnnotation(n); + Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL); if (assignable) Printv(f_shadow, ", ", module, ".", setname, NIL); - if (have_docstring(n)) - Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL); + if (have_docstring(n)) { + String *s = docstring(n, AUTODOC_VAR, tab4); + if (Len(s)) + Printv(f_shadow, ", doc=", s, NIL); + } Printv(f_shadow, ")\n", NIL); + Delete(variable_annotation); Delete(mname); Delete(setname); Delete(getname); @@ -5110,8 +5138,11 @@ public: Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL); if (assignable) Printv(f_shadow, ", ", module, ".", setname, NIL); - if (have_docstring(n)) - Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL); + if (have_docstring(n)) { + String *s = docstring(n, AUTODOC_VAR, tab4); + if (Len(s)) + Printv(f_shadow, ", doc=", s, NIL); + } Printv(f_shadow, ")\n", NIL); } String *getter = Getattr(n, "pybuiltin:getter"); diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index ca9ce649c..3283c96ab 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -5,7 +5,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * r.cxx * @@ -805,7 +805,7 @@ int R::DumpCode(Node *n) { File *scode = NewFile(output_filename, "w", SWIG_output_files()); if (!scode) { FileErrorDisplay(output_filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(output_filename); @@ -820,7 +820,7 @@ int R::DumpCode(Node *n) { File *runtime = NewFile(outfile,"w", SWIG_output_files()); if (!runtime) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Printf(runtime, "%s", f_begin); @@ -837,7 +837,7 @@ int R::DumpCode(Node *n) { File *ns = NewFile(output_filename, "w", SWIG_output_files()); if (!ns) { FileErrorDisplay(output_filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } Delete(output_filename); @@ -940,7 +940,7 @@ int R::OutputClassMethodsTable(File *) { * 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 + * out - the stream where the code is to be written. This is the S * code stream as we generate only S code here. * --------------------------------------------------------------*/ @@ -1542,8 +1542,6 @@ List * R::Swig_overload_rank(Node *n, if (nodes[i].error) Setattr(nodes[i].n, "overload:ignore", "1"); Append(result,nodes[i].n); - // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms)); - // Swig_print_node(nodes[i].n); } } return result; @@ -2740,7 +2738,7 @@ void R::main(int argc, char *argv[]) { } else if (strcmp(argv[i], "-nocppcast") == 0) { Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); Swig_mark_arg(i); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (debugMode) { diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index d00ffa35c..855e8d57d 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * ruby.cxx * @@ -898,7 +898,7 @@ public: } else if (strcmp(argv[i], "-nocppcast") == 0) { Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); Swig_mark_arg(i); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } } @@ -1037,13 +1037,13 @@ public: if (!outfile) { Printf(stderr, "Unable to determine outfile\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); @@ -1058,12 +1058,12 @@ public: if (directorsEnabled()) { if (!outfile_h) { Printf(stderr, "Unable to determine outfile_h\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); if (!f_runtime_h) { FileErrorDisplay(outfile_h); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index 9c8e374a0..a99ce0025 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -4,16 +4,16 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * scilab.cxx * * Scilab language module for SWIG. * --------------------------------------------------------------------------*/ +#include "swigmod.h" #include <cstddef> #include <cstdlib> -#include "swigmod.h" static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24; @@ -183,7 +183,7 @@ public: beginSection = NewFile(outputFilename, "w", SWIG_output_files()); if (!beginSection) { FileErrorDisplay(outputFilename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } runtimeSection = NewString(""); initSection = NewString(""); @@ -252,7 +252,7 @@ public: // Add Builder footer code and save if (generateBuilder) { - saveBuilderFile(gatewayName); + saveBuilderFile(gatewayLibraryName); } /* Close the init function and rename with module name */ @@ -345,7 +345,7 @@ public: } /* Write the wrapper function definition (standard Scilab gateway function prototype) */ - Printv(wrapper->def, "int ", overloadedName, "(SWIG_GatewayParameters) {", NIL); + Printv(wrapper->def, "SWIGEXPORT int ", overloadedName, "(SWIG_GatewayParameters) {", NIL); /* Emit all of the local variables for holding arguments */ // E.g.: double arg1; @@ -556,7 +556,7 @@ public: String *dispatch = Swig_overload_dispatch(node, "return %s(SWIG_GatewayArguments);", &maxargs); String *tmp = NewString(""); - Printv(wrapper->def, "int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL); + Printv(wrapper->def, "SWIGEXPORT int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL); /* Get the number of the parameters */ Wrapper_add_local(wrapper, "argc", "int argc = SWIG_NbInputArgument(pvApiCtx)"); @@ -600,7 +600,7 @@ public: String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallVariableName); Setattr(node, "wrap:name", getFunctionName); - Printv(getFunctionWrapper->def, "int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL); + Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL); /* Check the number of input and output */ Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n"); @@ -630,7 +630,7 @@ public: String *scilabSetSmallFunctionName = Swig_name_set(NSPACE_TODO, smallVariableName); Setattr(node, "wrap:name", setFunctionName); - Printv(setFunctionWrapper->def, "int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL); + Printv(setFunctionWrapper->def, "SWIGEXPORT int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL); /* Check the number of input and output */ Printf(setFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 1, 1);\n"); @@ -714,7 +714,7 @@ public: String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallConstantName); Setattr(node, "wrap:name", getFunctionName); Setattr(node, "wrap:name", getFunctionName); - Printv(getFunctionWrapper->def, "int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL); + Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL); /* Check the number of input and output */ Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n"); @@ -824,12 +824,14 @@ public: builderFile = NewFile(builderFilename, "w", SWIG_output_files()); if (!builderFile) { FileErrorDisplay(builderFilename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } emitBanner(builderFile); builderFunctionCount = 0; builderCode = NewString(""); + builderCode5 = NewString(""); + builderCode6 = NewString(""); Printf(builderCode, "mode(-1);\n"); Printf(builderCode, "lines(0);\n"); /* Useful for automatic tests */ @@ -933,8 +935,8 @@ public: Printf(builderCode, "if ierr <> 0 then\n"); Printf(builderCode, " error(ierr, err_msg);\n"); Printf(builderCode, "end\n"); - Write(builderFile, builderCode, Len(builderCode)); - + Printv(builderFile, builderCode, NIL); + Delete(builderCode); Delete(builderFile); } @@ -949,17 +951,13 @@ public: gatewayXMLFile = NewFile(gatewayXMLFilename, "w", SWIG_output_files()); if (!gatewayXMLFile) { FileErrorDisplay(gatewayXMLFilename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } // Add a slightly modified SWIG banner to the gateway XML ("--modify" is illegal in XML) gatewayXML = NewString(""); Printf(gatewayXML, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); Printf(gatewayXML, "<!--\n"); - Printf(gatewayXML, "This file was automatically generated by SWIG (http://www.swig.org).\n"); - Printf(gatewayXML, "Version %s\n", Swig_package_version()); - Printf(gatewayXML, "\n"); - Printf(gatewayXML, "Do not make changes to this file unless you know what you are doing - modify\n"); - Printf(gatewayXML, "the SWIG interface file instead.\n"); + Swig_banner_target_lang(gatewayXML, ""); Printf(gatewayXML, "-->\n"); Printf(gatewayXML, "<GATEWAY name=\"%s\">\n", gatewayName); @@ -998,7 +996,7 @@ public: Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); Printf(gatewayHeaderV6, "extern \"C\"\n"); Printf(gatewayHeaderV6, "#endif\n"); - Printf(gatewayHeaderV6, "int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName); + Printf(gatewayHeaderV6, "SWIGEXPORT int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName); Printf(gatewayHeaderV6, "\n"); } @@ -1029,7 +1027,7 @@ public: Printf(gatewayHeaderV5, "#ifdef __cplusplus\n"); Printf(gatewayHeaderV5, "extern \"C\" {\n"); Printf(gatewayHeaderV5, "#endif\n"); - Printf(gatewayHeaderV5, "int C2F(%s)() {\n", gatewayLibraryName); + Printf(gatewayHeaderV5, "SWIGEXPORT int C2F(%s)() {\n", gatewayLibraryName); Printf(gatewayHeaderV5, " Rhs = Max(0, Rhs);\n"); Printf(gatewayHeaderV5, " if (*(Tab[Fin-1].f) != NULL) {\n"); Printf(gatewayHeaderV5, " if(pvApiCtx == NULL) {\n"); @@ -1066,7 +1064,7 @@ public: loaderFile = NewFile(loaderFilename, "w", SWIG_output_files()); if (!loaderFile) { FileErrorDisplay(loaderFilename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } emitBanner(loaderFile); diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 84ac74294..bb5bf34e5 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigmain.cxx * @@ -80,15 +80,10 @@ static TargetLanguageModule modules[] = { {"-tcl", swig_tcl, NULL, Supported}, {"-tcl8", swig_tcl, "Tcl 8", Supported}, {"-uffi", NULL, "Common Lisp / UFFI", Disabled}, - {"-xml", swig_xml, "XML", Supported}, + {"-xml", swig_xml, "XML", Experimental}, {NULL, NULL, NULL, Disabled} }; -#ifdef MACSWIG -#include <console.h> -#include <SIOUX.h> -#endif - //----------------------------------------------------------------- // main() // @@ -98,15 +93,15 @@ static TargetLanguageModule modules[] = { void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) { if (!env) { *nargc = oargc; - *nargv = (char **)malloc(sizeof(char *) * (oargc + 1)); + *nargv = (char **)Malloc(sizeof(char *) * (oargc + 1)); memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1)); return; } int argc = 1; int arge = oargc + 1024; - char **argv = (char **) malloc(sizeof(char *) * (arge + 1)); - char *buffer = (char *) malloc(2048); + char **argv = (char **) Malloc(sizeof(char *) * (arge + 1)); + char *buffer = (char *) Malloc(2048); char *b = buffer; char *be = b + 1023; const char *c = env; @@ -139,11 +134,11 @@ static void insert_option(int *argc, char ***argv, int index, char const *start, size_t option_len = end - start; // Preserve the NULL pointer at argv[argc] - new_argv = (char **)realloc(new_argv, (new_argc + 2) * sizeof(char *)); + new_argv = (char **)Realloc(new_argv, (new_argc + 2) * sizeof(char *)); memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index)); new_argc++; - new_argv[index] = (char *)malloc(option_len + 1); + new_argv[index] = (char *)Malloc(option_len + 1); memcpy(new_argv[index], start, option_len); new_argv[index][option_len] = '\0'; @@ -222,11 +217,6 @@ int main(int margc, char **margv) { SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv); merge_options_files(&argc, &argv); -#ifdef MACSWIG - SIOUXSettings.asktosaveonclose = false; - argc = ccommand(&argv); -#endif - Swig_init_args(argc, argv); /* Get options */ @@ -247,7 +237,7 @@ int main(int margc, char **margv) { Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help); else Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) { if (strcmp(argv[i], "--help") == 0) diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index bfb93d1a7..11b13f9fc 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigmod.h * * Main header file for SWIG modules. * ----------------------------------------------------------------------------- */ -#ifndef SWIG_SWIGMOD_H_ -#define SWIG_SWIGMOD_H_ +#ifndef SWIG_SWIGMOD_H +#define SWIG_SWIGMOD_H #include "swig.h" #include "preprocessor.h" @@ -196,7 +196,7 @@ public: virtual int classDirector(Node *n); virtual int classDirectorInit(Node *n); virtual int classDirectorEnd(Node *n); - virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase = 0); + virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase = 0); virtual int classDirectorConstructor(Node *n); virtual int classDirectorDefaultConstructor(Node *n); virtual int classDirectorMethod(Node *n, Node *parent, String *super); @@ -346,6 +346,8 @@ protected: class DoxygenTranslator *doxygenTranslator; private: + void unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase); + Hash *symtabs; /* symbol tables */ int overloading; int multiinput; @@ -428,16 +430,14 @@ extern "C" { void Swig_print_with_location(DOH *object, int count = -1); } +void Swig_default_allocators(Node *n); +void Swig_process_types(Node *n); + /* Contracts */ void Swig_contracts(Node *n); void Swig_contract_mode_set(int flag); int Swig_contract_mode_get(); -/* Browser */ -void Swig_browser(Node *n, int); -void Swig_default_allocators(Node *n); -void Swig_process_types(Node *n); - /* Nested classes */ void Swig_nested_process_classes(Node *n); void Swig_nested_name_unnamed_c_structs(Node *n); diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx index d90d1d3b1..f65b3eccf 100644 --- a/Source/Modules/tcl8.cxx +++ b/Source/Modules/tcl8.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * tcl8.cxx * @@ -113,7 +113,7 @@ public: } else if (strcmp(argv[i], "-nocppcast") == 0) { Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); Swig_mark_arg(i); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } } @@ -138,7 +138,7 @@ public: f_begin = NewFile(outfile, "w", SWIG_output_files()); if (!f_begin) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_runtime = NewString(""); f_init = NewString(""); @@ -182,7 +182,7 @@ public: if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) { FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } f_shadow_stubs = NewString(""); @@ -825,6 +825,7 @@ public: //Printf(f_init,"/* Register base : %s */\n", bmangle); //Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname)); + (void)index; b = Next(b); index++; Putc(',', base_class); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index d1a16b53a..2a1dadf73 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * typepass.cxx * @@ -969,7 +969,7 @@ class TypePass:private Dispatcher { if (Getattr(c, "sym:overloaded") != checkoverloaded) { Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded); Swig_print_node(c); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl"); @@ -977,7 +977,7 @@ class TypePass:private Dispatcher { if (!Getattr(c, "sym:overloaded")) { Printf(stdout, "sym:overloaded error.....%p\n", c); Swig_print_node(c); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } c = Getattr(c, "sym:nextSibling"); } @@ -1039,6 +1039,21 @@ class TypePass:private Dispatcher { Node *unodes = 0, *last_unodes = 0; int ccount = 0; String *symname = Getattr(n, "sym:name"); + + // The overloaded functions in scope may not yet have had their parameters normalized yet (in cDeclaration). + // Happens if the functions were declared after the using declaration. So use a normalized copy. + List *n_decl_list = NewList(); + Node *over = Getattr(n, "sym:overloaded"); + while (over) { + String *odecl = Copy(Getattr(over, "decl")); + if (odecl) { + normalize_type(odecl); + Append(n_decl_list, odecl); + Delete(odecl); + } + over = Getattr(over, "sym:nextSibling"); + } + while (c) { if (Strcmp(nodeType(c), "cdecl") == 0) { if (!(Swig_storage_isstatic(c) @@ -1049,30 +1064,28 @@ class TypePass:private Dispatcher { String *csymname = Getattr(c, "sym:name"); if (!csymname || (Strcmp(csymname, symname) == 0)) { - { - String *decl = Getattr(c, "decl"); - Node *over = Getattr(n, "sym:overloaded"); - int match = 0; - while (over) { - String *odecl = Getattr(over, "decl"); - if (Cmp(decl, odecl) == 0) { - match = 1; - break; - } - over = Getattr(over, "sym:nextSibling"); - } - if (match) { - /* Don't generate a method if the method is overridden in this class, - * for example don't generate another m(bool) should there be a Base::m(bool) : - * struct Derived : Base { - * void m(bool); - * using Base::m; - * }; - */ - c = Getattr(c, "csym:nextSibling"); - continue; + String *decl = Getattr(c, "decl"); + int match = 0; + + for (Iterator it = First(n_decl_list); it.item; it = Next(it)) { + String *odecl = it.item; + if (Cmp(decl, odecl) == 0) { + match = 1; + break; } } + if (match) { + /* Don't generate a method if the method is overridden in this class, + * for example don't generate another m(bool) should there be a Base::m(bool) : + * struct Derived : Base { + * void m(bool); + * using Base::m; + * }; + */ + c = Getattr(c, "csym:nextSibling"); + continue; + } + Node *nn = copyNode(c); Setfile(nn, Getfile(n)); Setline(nn, Getline(n)); @@ -1080,6 +1093,9 @@ class TypePass:private Dispatcher { Setattr(nn, "access", Getattr(n, "access")); if (!Getattr(nn, "sym:name")) Setattr(nn, "sym:name", symname); + Symtab *st = Getattr(n, "sym:symtab"); + assert(st); + Setattr(nn, "sym:symtab", st); if (!GetFlag(nn, "feature:ignore")) { ParmList *parms = CopyParmList(Getattr(c, "parms")); @@ -1143,14 +1159,30 @@ class TypePass:private Dispatcher { * which is hacked. */ if (Getattr(n, "sym:overloaded")) { int cnt = 0; + Node *ps = Getattr(n, "sym:previousSibling"); + Node *ns = Getattr(n, "sym:nextSibling"); + Node *fc = firstChild(n); + Node *firstoverloaded = Getattr(n, "sym:overloaded"); #ifdef DEBUG_OVERLOADED - Node *debugnode = n; - show_overloaded(n); + show_overloaded(firstoverloaded); #endif - if (!firstChild(n)) { + + if (firstoverloaded == n) { + // This 'using' node we are cutting out was the first node in the overloaded list. + // Change the first node in the list + Delattr(firstoverloaded, "sym:overloaded"); + firstoverloaded = fc ? fc : ns; + + // Correct all the sibling overloaded methods (before adding in new methods) + Node *nnn = ns; + while (nnn) { + Setattr(nnn, "sym:overloaded", firstoverloaded); + nnn = Getattr(nnn, "sym:nextSibling"); + } + } + + if (!fc) { // Remove from overloaded list ('using' node does not actually end up adding in any methods) - Node *ps = Getattr(n, "sym:previousSibling"); - Node *ns = Getattr(n, "sym:nextSibling"); if (ps) { Setattr(ps, "sym:nextSibling", ns); } @@ -1158,24 +1190,8 @@ class TypePass:private Dispatcher { Setattr(ns, "sym:previousSibling", ps); } } else { - // The 'using' node results in methods being added in - slot in the these methods here - Node *ps = Getattr(n, "sym:previousSibling"); - Node *ns = Getattr(n, "sym:nextSibling"); - Node *fc = firstChild(n); + // The 'using' node results in methods being added in - slot in these methods here Node *pp = fc; - - Node *firstoverloaded = Getattr(n, "sym:overloaded"); - if (firstoverloaded == n) { - // This 'using' node we are cutting out was the first node in the overloaded list. - // Change the first node in the list to its first sibling - Delattr(firstoverloaded, "sym:overloaded"); - Node *nnn = Getattr(firstoverloaded, "sym:nextSibling"); - firstoverloaded = fc; - while (nnn) { - Setattr(nnn, "sym:overloaded", firstoverloaded); - nnn = Getattr(nnn, "sym:nextSibling"); - } - } while (pp) { Node *ppn = Getattr(pp, "sym:nextSibling"); Setattr(pp, "sym:overloaded", firstoverloaded); @@ -1193,19 +1209,17 @@ class TypePass:private Dispatcher { Setattr(ns, "sym:previousSibling", pp); Setattr(pp, "sym:nextSibling", ns); } -#ifdef DEBUG_OVERLOADED - debugnode = firstoverloaded; -#endif } Delattr(n, "sym:previousSibling"); Delattr(n, "sym:nextSibling"); Delattr(n, "sym:overloaded"); Delattr(n, "sym:overname"); + clean_overloaded(firstoverloaded); #ifdef DEBUG_OVERLOADED - show_overloaded(debugnode); + show_overloaded(firstoverloaded); #endif - clean_overloaded(n); // Needed? } + Delete(n_decl_list); } } } else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) { diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx index 2964ed3a6..de6f87d8c 100644 --- a/Source/Modules/utils.cxx +++ b/Source/Modules/utils.cxx @@ -4,14 +4,14 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * utils.cxx * * Various utility functions. * ----------------------------------------------------------------------------- */ -#include <swigmod.h> +#include "swigmod.h" int is_public(Node *n) { String *access = Getattr(n, "access"); diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx index 5f090561a..5830754b4 100644 --- a/Source/Modules/xml.cxx +++ b/Source/Modules/xml.cxx @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * xml.cxx * @@ -52,7 +52,7 @@ public: out = NewFile(outfile, "w", SWIG_output_files()); if (!out) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } continue; } @@ -89,7 +89,7 @@ public: out = NewFile(outfile, "w", SWIG_output_files()); if (!out) { FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } Printf(out, "<?xml version=\"1.0\" ?> \n"); @@ -310,7 +310,7 @@ void Swig_print_xml(DOH *obj, String *filename) { out = NewFile(filename, "w", SWIG_output_files()); if (!out) { FileErrorDisplay(filename); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c index 1ede58354..a80434323 100644 --- a/Source/Preprocessor/cpp.c +++ b/Source/Preprocessor/cpp.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * cpp.c * @@ -741,14 +741,35 @@ static String *get_options(String *str) { opt = NewString("("); while (((c = Getc(str)) != EOF)) { Putc(c, opt); - if (c == ')') { - level--; - if (!level) - return opt; + switch (c) { + case ')': + level--; + if (!level) + return opt; + break; + case '(': + level++; + break; + case '"': + /* Skip over quoted strings */ + while (1) { + c = Getc(str); + if (c == EOF) + goto bad; + Putc(c, opt); + if (c == '"') + break; + if (c == '\\') { + c = Getc(str); + if (c == EOF) + goto bad; + Putc(c, opt); + } + } + break; } - if (c == '(') - level++; } +bad: Delete(opt); return 0; } else { @@ -1335,14 +1356,14 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) { push/pop_imported(): helper functions for defining and undefining SWIGIMPORTED (when %importing a file). */ -static void push_imported() { +static void push_imported(void) { if (imported_depth == 0) { Preprocessor_define("SWIGIMPORTED 1", 0); } ++imported_depth; } -static void pop_imported() { +static void pop_imported(void) { --imported_depth; if (imported_depth == 0) { Preprocessor_undef("SWIGIMPORTED"); @@ -2055,8 +2076,7 @@ String *Preprocessor_parse(String *s) { break; default: Printf(stderr, "cpp: Invalid parser state %d\n", state); - abort(); - break; + Exit(EXIT_FAILURE); } } while (level > 0) { diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c index d7a65a77e..95e05cf56 100644 --- a/Source/Preprocessor/expr.c +++ b/Source/Preprocessor/expr.c @@ -4,12 +4,17 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * expr.c * * Integer arithmetic expression evaluator used to handle expressions * encountered during preprocessing. + * + * Note that this is used for expressions in `#if` and the like, but not + * for expressions in `#define` which SWIG wraps as constants - for those + * we inject a `%constant` directive which is handled by the parser in + * `Source/CParse/parser.y`. * ----------------------------------------------------------------------------- */ #include "swig.h" @@ -52,8 +57,9 @@ static int expr_init = 0; /* Initialization flag */ static const char *errmsg = 0; /* Parsing error */ /* Initialize the precedence table for various operators. Low values have higher precedence */ -static void init_precedence() { +static void init_precedence(void) { prec[SWIG_TOKEN_NOT] = 10; + prec[SWIG_TOKEN_LNOT] = 10; prec[OP_UMINUS] = 10; prec[OP_UPLUS] = 10; prec[SWIG_TOKEN_STAR] = 20; @@ -63,16 +69,15 @@ static void init_precedence() { prec[SWIG_TOKEN_MINUS] = 30; prec[SWIG_TOKEN_LSHIFT] = 40; prec[SWIG_TOKEN_RSHIFT] = 40; - prec[SWIG_TOKEN_AND] = 50; - prec[SWIG_TOKEN_XOR] = 60; - prec[SWIG_TOKEN_OR] = 70; - prec[SWIG_TOKEN_EQUALTO] = 80; - prec[SWIG_TOKEN_NOTEQUAL] = 80; - prec[SWIG_TOKEN_LESSTHAN] = 80; - prec[SWIG_TOKEN_GREATERTHAN] = 80; - prec[SWIG_TOKEN_LTEQUAL] = 80; - prec[SWIG_TOKEN_GTEQUAL] = 80; - prec[SWIG_TOKEN_LNOT] = 90; + prec[SWIG_TOKEN_LESSTHAN] = 50; + prec[SWIG_TOKEN_GREATERTHAN] = 50; + prec[SWIG_TOKEN_LTEQUAL] = 50; + prec[SWIG_TOKEN_GTEQUAL] = 50; + prec[SWIG_TOKEN_EQUALTO] = 60; + prec[SWIG_TOKEN_NOTEQUAL] = 60; + prec[SWIG_TOKEN_AND] = 70; + prec[SWIG_TOKEN_XOR] = 80; + prec[SWIG_TOKEN_OR] = 90; prec[SWIG_TOKEN_LAND] = 100; prec[SWIG_TOKEN_LOR] = 110; expr_init = 1; @@ -85,7 +90,7 @@ static void init_precedence() { /* Reduce a single operator on the stack */ /* return 0 on failure, 1 on success */ -static int reduce_op() { +static int reduce_op(void) { long op_token = stack[sp - 1].value; assert(sp > 0); assert(stack[sp - 1].op == EXPR_OP); @@ -318,7 +323,12 @@ int Preprocessor_expr(DOH *s, int *error) { if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) { /* A number. Reduce EXPR_TOP to an EXPR_VALUE */ char *c = Char(Scanner_text(scan)); - stack[sp].value = (long) strtol(c, 0, 0); + if (c[0] == '0' && (c[1] == 'b' || c[1] == 'B')) { + /* strtol() doesn't handle binary constants */ + stack[sp].value = (long) strtol(c + 2, 0, 2); + } else { + stack[sp].value = (long) strtol(c, 0, 0); + } stack[sp].svalue = 0; stack[sp].op = EXPR_VALUE; } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_PLUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) { @@ -435,6 +445,8 @@ int Preprocessor_expr(DOH *s, int *error) { stack[sp - 1].svalue = stack[sp].svalue; sp--; break; + case SWIG_TOKEN_LTEQUALGT: + goto spaceship_not_allowed; default: goto syntax_error_expected_operator; break; @@ -443,7 +455,7 @@ int Preprocessor_expr(DOH *s, int *error) { default: fprintf(stderr, "Internal error in expression evaluator.\n"); - abort(); + Exit(EXIT_FAILURE); } } @@ -466,6 +478,11 @@ extra_rparen: errmsg = "Extra \')\'"; *error = 1; return 0; + +spaceship_not_allowed: + errmsg = "Spaceship operator (<=>) not allowed in preprocessor expression"; + *error = 1; + return 0; } /* ----------------------------------------------------------------------------- @@ -474,6 +491,6 @@ extra_rparen: * Return error message set by the evaluator (if any) * ----------------------------------------------------------------------------- */ -const char *Preprocessor_expr_error() { +const char *Preprocessor_expr_error(void) { return errmsg; } diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h index 4c24f48d0..c1a30da79 100644 --- a/Source/Preprocessor/preprocessor.h +++ b/Source/Preprocessor/preprocessor.h @@ -4,15 +4,15 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * preprocessor.h * * SWIG preprocessor module. * ----------------------------------------------------------------------------- */ -#ifndef SWIG_PREPROCESSOR_H_ -#define SWIG_PREPROCESSOR_H_ +#ifndef SWIG_PREPROCESSOR_H +#define SWIG_PREPROCESSOR_H #include "swigwarn.h" diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index ebe9fa702..36d207050 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * cwrap.c * @@ -15,6 +15,8 @@ #include "swig.h" #include "cparse.h" +extern int UseWrapperSuffix; // from main.cxx + static const char *cresult_variable_name = "result"; static Parm *nonvoid_parms(Parm *p) { @@ -427,10 +429,14 @@ String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) { String *rcaststr = SwigType_rcaststr(rpt, pname); if (comma) { - Printv(func, ",", rcaststr, NIL); - } else { - Append(func, rcaststr); + Append(func, ","); } + + if (cparse_cplusplus && SwigType_type(rpt) == T_USER) + Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL); + else + Printv(func, rcaststr, NIL); + Delete(rpt); Delete(pname); Delete(rcaststr); @@ -1079,13 +1085,13 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas in C. But when not using the suffix used for overloaded functions, we still need to ensure that the - wrapper name doesn't conflict with any wrapper functions, so make it sufficiently unique by - appending a suffix similar to the one used for overloaded functions to it. + wrapper name doesn't conflict with any wrapper functions for some languages, so optionally make + it sufficiently unique by appending a suffix similar to the one used for overloaded functions to it. */ if (code) { if (Getattr(n, "sym:overloaded")) { Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname")); - } else { + } else if (UseWrapperSuffix) { Append(mangled, "__SWIG"); } } diff --git a/Source/Swig/deprecate.c b/Source/Swig/deprecate.c index 08dc06a66..5783455e5 100644 --- a/Source/Swig/deprecate.c +++ b/Source/Swig/deprecate.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * deprecate.c * diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 1dde06652..efd644f9a 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * error.c * @@ -209,14 +209,14 @@ void Swig_warnfilter(const_String_or_char_ptr wlist, int add) { Insert(filter, 0, "-"); } } else { - char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2); + char *temp = (char *)Malloc(sizeof(char)*strlen(c) + 2); if (isdigit((int) *c)) { sprintf(temp, "-%s", c); } else { strcpy(temp, c); } Replace(filter, temp, "", DOH_REPLACE_FIRST); - free(temp); + Free(temp); } } c = strtok(NULL, ", "); diff --git a/Source/Swig/extend.c b/Source/Swig/extend.c index 70355a245..23660c0ad 100644 --- a/Source/Swig/extend.c +++ b/Source/Swig/extend.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * extend.c * diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c index 4ec26f955..03b231fa1 100644 --- a/Source/Swig/fragment.c +++ b/Source/Swig/fragment.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * fragment.c * diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c index 6970dc177..7791d13f7 100644 --- a/Source/Swig/getopt.c +++ b/Source/Swig/getopt.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * getopt.c * @@ -32,16 +32,12 @@ static int *marked; * ----------------------------------------------------------------------------- */ void Swig_init_args(int argc, char **argv) { - int i; assert(argc > 0); assert(argv); numargs = argc; args = argv; - marked = (int *) malloc(numargs * sizeof(int)); - for (i = 0; i < argc; i++) { - marked[i] = 0; - } + marked = (int *) Calloc(numargs, sizeof(int)); marked[0] = 1; } @@ -87,11 +83,11 @@ void Swig_check_options(int check_input) { } if (error) { Printf(stderr, "Use 'swig -help' for available options.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } if (check_input && marked[numargs - 1]) { Printf(stderr, "Must specify an input file. Use -help for available options.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -104,5 +100,5 @@ void Swig_check_options(int check_input) { void Swig_arg_error(void) { Printf(stderr, "SWIG : Unable to parse command line options.\n"); Printf(stderr, "Use 'swig -help' for available options.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } diff --git a/Source/Swig/include.c b/Source/Swig/include.c index 94df338f0..c153ac9b7 100644 --- a/Source/Swig/include.c +++ b/Source/Swig/include.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * include.c * @@ -110,11 +110,7 @@ static List *Swig_search_path_any(int syspath) { assert(slist); filename = NewStringEmpty(); assert(filename); -#ifdef MACSWIG - Printf(filename, "%s", SWIG_FILE_DELIMITER); -#else Printf(filename, ".%s", SWIG_FILE_DELIMITER); -#endif Append(slist, filename); Delete(filename); @@ -145,7 +141,7 @@ static List *Swig_search_path_any(int syspath) { return slist; } -List *Swig_search_path() { +List *Swig_search_path(void) { return Swig_search_path_any(0); } @@ -376,6 +372,6 @@ String *Swig_file_dirname(const_String_or_char_ptr filename) { /* * Swig_file_debug() */ -void Swig_file_debug_set() { +void Swig_file_debug_set(void) { file_debug = 1; } diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index d92d4e410..92e45fbe0 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * misc.c * @@ -36,7 +36,7 @@ static char *fake_version = 0; char *Swig_copy_string(const char *s) { char *c = 0; if (s) { - c = (char *) malloc(strlen(s) + 1); + c = (char *) Malloc(strlen(s) + 1); strcpy(c, s); } return c; @@ -69,15 +69,8 @@ const char *Swig_package_version(void) { * ----------------------------------------------------------------------------- */ void Swig_banner(File *f) { - Printf(f, "/* ----------------------------------------------------------------------------\n\ - * This file was automatically generated by SWIG (http://www.swig.org).\n\ - * Version %s\n\ - *\n\ - * This file is not intended to be easily readable and contains a number of\n\ - * coding conventions designed to improve portability and efficiency. Do not make\n\ - * changes to this file unless you know what you are doing--modify the SWIG\n\ - * interface file instead.\n", Swig_package_version()); - /* String too long for ISO compliance */ + Printf(f, "/* ----------------------------------------------------------------------------\n"); + Swig_banner_target_lang(f, " *"); Printf(f, " * ----------------------------------------------------------------------------- */\n"); } @@ -89,10 +82,10 @@ void Swig_banner(File *f) { * ----------------------------------------------------------------------------- */ void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) { - Printf(f, "%s This file was automatically generated by SWIG (http://www.swig.org).\n", commentchar); + Printf(f, "%s This file was automatically generated by SWIG (https://www.swig.org).\n", commentchar); Printf(f, "%s Version %s\n", commentchar, Swig_package_version()); Printf(f, "%s\n", commentchar); - Printf(f, "%s Do not make changes to this file unless you know what you are doing--modify\n", commentchar); + Printf(f, "%s Do not make changes to this file unless you know what you are doing - modify\n", commentchar); Printf(f, "%s the SWIG interface file instead.\n", commentchar); } @@ -218,7 +211,7 @@ void Swig_filename_correct(String *filename) { if (fname[0] == '/' && fname[1] == '/') network_path = 1; } -#if defined(_WIN32) || defined(MACSWIG) +#if defined(_WIN32) /* accept Unix path separator on non-Unix systems */ Replaceall(filename, "/", SWIG_FILE_DELIMITER); #endif @@ -1162,7 +1155,7 @@ int Swig_scopename_check(const String *s) { String *Swig_string_command(String *s) { Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); return 0; } @@ -1251,7 +1244,7 @@ void Swig_offset_string(String *s, int number) { if ((Char(s))[len-1] == '\n') --lines; /* allocate a temporary storage for a padded string */ - res = (char*)malloc(len + lines * number * 2 + 1); + res = (char*)Malloc(len + lines * number * 2 + 1); res[len + lines * number * 2] = 0; /* copy lines to res, prepending tabs to each line */ @@ -1275,7 +1268,7 @@ void Swig_offset_string(String *s, int number) { /* replace 's' contents with 'res' */ Clear(s); Append(s, res); - free(res); + Free(res); } @@ -1309,7 +1302,7 @@ static int split_regex_pattern_subst(String *s, String **pattern, String **subst err_out: Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); return 0; } @@ -1435,7 +1428,7 @@ String *Swig_string_regex(String *s) { pcre2_get_error_message (pcre_errornum, pcre_error, sizeof pcre_error); Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n", pcre_error, Char(pattern), pcre_errorpos); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL); rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); @@ -1445,7 +1438,7 @@ String *Swig_string_regex(String *s) { } else if (rc != PCRE2_ERROR_NOMATCH) { Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n", rc, Char(pattern), input); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } } @@ -1458,11 +1451,11 @@ String *Swig_string_regex(String *s) { String *Swig_pcre_version(void) { int len = pcre2_config(PCRE2_CONFIG_VERSION, NULL); - char *buf = malloc(len); + char *buf = Malloc(len); String *result; pcre2_config(PCRE2_CONFIG_VERSION, buf); result = NewStringf("PCRE2 Version: %s", buf); - free(buf); + Free(buf); return result; } @@ -1470,7 +1463,7 @@ String *Swig_pcre_version(void) { String *Swig_string_regex(String *s) { Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); return 0; } @@ -1497,7 +1490,7 @@ int Swig_is_generated_overload(Node *n) { * Initialize the SWIG core * ----------------------------------------------------------------------------- */ -void Swig_init() { +void Swig_init(void) { /* Set some useful string encoding methods */ DohEncoding("escape", Swig_string_escape); DohEncoding("hexescape", Swig_string_hexescape); diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index c9456637b..c4613f6c6 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * naming.c * @@ -744,28 +744,28 @@ void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *d * ----------------------------------------------------------------------------- */ static Hash *namewarn_hash = 0; -static Hash *name_namewarn_hash() { +static Hash *name_namewarn_hash(void) { if (!namewarn_hash) namewarn_hash = NewHash(); return namewarn_hash; } static Hash *rename_hash = 0; -static Hash *name_rename_hash() { +static Hash *name_rename_hash(void) { if (!rename_hash) rename_hash = NewHash(); return rename_hash; } static List *namewarn_list = 0; -static List *name_namewarn_list() { +static List *name_namewarn_list(void) { if (!namewarn_list) namewarn_list = NewList(); return namewarn_list; } static List *rename_list = 0; -static List *name_rename_list() { +static List *name_rename_list(void) { if (!rename_list) rename_list = NewList(); return rename_list; @@ -1101,6 +1101,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) { int errornum; size_t errpos; int rc; + pcre2_match_data *match_data = 0; compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL); if (!compiled_pat) { @@ -1108,10 +1109,9 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) { Swig_error("SWIG", Getline(n), "Invalid regex \"%s\": compilation failed at %d: %s\n", Char(pattern), errpos, err); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } - pcre2_match_data *match_data = 0; match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL); rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0); pcre2_code_free(compiled_pat); @@ -1124,7 +1124,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) { Swig_error("SWIG", Getline(n), "Matching \"%s\" against regex \"%s\" failed: %d\n", Char(s), Char(pattern), rc); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } return 1; @@ -1137,7 +1137,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) { (void)s; Swig_error("SWIG", Getline(n), "PCRE regex matching is not available in this SWIG build.\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); return 0; } diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c index 3e832c361..11071ce0c 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * parms.c * @@ -149,7 +149,7 @@ int ParmList_len(ParmList *p) { * get_empty_type() * ---------------------------------------------------------------------- */ -static SwigType *get_empty_type() { +static SwigType *get_empty_type(void) { return NewStringEmpty(); } diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index f53454b4b..9dbb35364 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * scanner.c * @@ -56,7 +56,7 @@ static void brackets_clear(Scanner *); Scanner *NewScanner(void) { Scanner *s; - s = (Scanner *) malloc(sizeof(Scanner)); + s = (Scanner *) Malloc(sizeof(Scanner)); s->line = 1; s->file = 0; s->nexttoken = -1; @@ -88,8 +88,8 @@ void DelScanner(Scanner *s) { Delete(s->file); Delete(s->error); Delete(s->str); - free(s->idstart); - free(s); + Free(s->idstart); + Free(s); } /* ----------------------------------------------------------------------------- @@ -202,7 +202,7 @@ int Scanner_start_line(Scanner *s) { * ----------------------------------------------------------------------------- */ void Scanner_idstart(Scanner *s, const char *id) { - free(s->idstart); + Free(s->idstart); s->idstart = Swig_copy_string(id); } @@ -336,9 +336,9 @@ static void brackets_reset(Scanner *s) { * Usually called when '(' is found. * ----------------------------------------------------------------------------- */ static void brackets_push(Scanner *s) { - int *newInt = (int *)malloc(sizeof(int)); + int *newInt = (int *)Malloc(sizeof(int)); *newInt = 0; - Push(s->brackets, NewVoid(newInt, free)); + Push(s->brackets, NewVoid(newInt, Free)); } /* ----------------------------------------------------------------------------- @@ -596,10 +596,6 @@ static int look(Scanner *s) { state = 3; else if (c == '\\') return SWIG_TOKEN_BACKSLASH; - else if (c == '[') - return SWIG_TOKEN_LBRACKET; - else if (c == ']') - return SWIG_TOKEN_RBRACKET; else if (c == '@') return SWIG_TOKEN_AT; else if (c == '$') @@ -637,6 +633,10 @@ static int look(Scanner *s) { else if (c == '.') state = 100; /* Maybe a number, maybe ellipsis, just a period */ + else if (c == '[') + state = 102; /* Maybe a bracket or a double bracket */ + else if (c == ']') + state = 103; /* Maybe a bracket or a double bracket */ else if (isdigit(c)) state = 8; /* A numerical value */ else @@ -833,7 +833,7 @@ static int look(Scanner *s) { return SWIG_TOKEN_MODEQUAL; } else if (c == '}') { Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n"); - SWIG_exit(EXIT_FAILURE); + Exit(EXIT_FAILURE); } else { retract(s, 1); return SWIG_TOKEN_PERCENT; @@ -893,9 +893,16 @@ static int look(Scanner *s) { } if (c == '<') state = 240; - else if (c == '=') - return SWIG_TOKEN_LTEQUAL; - else { + else if (c == '=') { + if ((c = nextchar(s)) == 0) { + return SWIG_TOKEN_LTEQUAL; + } else if (c == '>' && cparse_cplusplus) { /* Spaceship operator */ + return SWIG_TOKEN_LTEQUALGT; + } else { + retract(s, 1); + return SWIG_TOKEN_LTEQUAL; + } + } else { retract(s, 1); brackets_increment(s); return SWIG_TOKEN_LESSTHAN; @@ -1358,6 +1365,31 @@ static int look(Scanner *s) { } break; + /* A left bracket or a double left bracket */ + case 102: + + if ((c = nextchar(s)) == 0) { + return SWIG_TOKEN_LBRACKET; + } else if (c == '[') { + return SWIG_TOKEN_LLBRACKET; + } else { + retract(s, 1); + return SWIG_TOKEN_LBRACKET; + } + break; + + /* a right bracket or a double right bracket */ + case 103: + if ((c = nextchar(s)) == 0) { + return SWIG_TOKEN_RBRACKET; + } else if (c == ']') { + return SWIG_TOKEN_RRBRACKET; + } else { + retract(s, 1); + return SWIG_TOKEN_RBRACKET; + } + break; + case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_PLUS; @@ -1811,14 +1843,14 @@ void Scanner_locator(Scanner *s, String *loc) { cparse_file = locs->filename; cparse_line = locs->line_number; l = locs->next; - free(locs); + Free(locs); locs = l; } return; } /* We're going to push a new location */ - l = (Locator *) malloc(sizeof(Locator)); + l = (Locator *) Malloc(sizeof(Locator)); l->filename = cparse_file; l->line_number = cparse_line; l->next = locs; diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 5f876ff04..f227778f6 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * stype.c * diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 2bf3e08b0..943f5daf0 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -4,19 +4,17 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swig.h * * Header file for the SWIG core. * ----------------------------------------------------------------------------- */ -#ifndef SWIGCORE_H_ -#define SWIGCORE_H_ +#ifndef SWIG_SWIG_H +#define SWIG_SWIG_H -#ifndef MACSWIG #include "swigconfig.h" -#endif #include <stdio.h> #include <string.h> @@ -441,8 +439,6 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern void Language_replace_special_variables(String *method, String *tm, Parm *parm); extern void Swig_print(DOH *object, int count); extern void Swig_print_with_location(DOH *object, int count); - extern void SWIG_exit(int exit_code); - /* -- template init -- */ extern void SwigType_template_init(void); diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h index f12b33081..009599a11 100644 --- a/Source/Swig/swigfile.h +++ b/Source/Swig/swigfile.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigfile.h * @@ -30,13 +30,11 @@ extern String *Swig_file_extension(const_String_or_char_ptr filename); extern String *Swig_file_basename(const_String_or_char_ptr filename); extern String *Swig_file_filename(const_String_or_char_ptr filename); extern String *Swig_file_dirname(const_String_or_char_ptr filename); -extern void Swig_file_debug_set(); +extern void Swig_file_debug_set(void); /* Delimiter used in accessing files and directories */ -#if defined(MACSWIG) -# define SWIG_FILE_DELIMITER ":" -#elif defined(_WIN32) +#if defined(_WIN32) # define SWIG_FILE_DELIMITER "\\" #else # define SWIG_FILE_DELIMITER "/" diff --git a/Source/Swig/swigopt.h b/Source/Swig/swigopt.h index 543bfb819..86a477b8f 100644 --- a/Source/Swig/swigopt.h +++ b/Source/Swig/swigopt.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigopt.h * diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h index 7b27df5f6..7b63546ec 100644 --- a/Source/Swig/swigparm.h +++ b/Source/Swig/swigparm.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigparm.h * diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h index 4f66de8a2..6c9d1ff7f 100644 --- a/Source/Swig/swigscan.h +++ b/Source/Swig/swigscan.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigscan.h * @@ -71,6 +71,8 @@ extern void Scanner_locator(Scanner *, String *loc); #define SWIG_TOKEN_WSTRING 33 /* L"str" */ #define SWIG_TOKEN_WCHAR 34 /* L'c' */ #define SWIG_TOKEN_ELLIPSIS 35 /* ... */ +#define SWIG_TOKEN_LLBRACKET 36 /* [[ */ +#define SWIG_TOKEN_RRBRACKET 37 /* ]] */ #define SWIG_TOKEN_ILLEGAL 99 #define SWIG_TOKEN_ERROR -1 @@ -114,3 +116,4 @@ extern void Scanner_locator(Scanner *, String *loc); #define SWIG_TOKEN_MODEQUAL 134 /* %= */ #define SWIG_TOKEN_ARROW 135 /* -> */ #define SWIG_TOKEN_ARROWSTAR 136 /* ->* */ +#define SWIG_TOKEN_LTEQUALGT 137 /* <=> */ diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h index acd0e5e90..8d63d8fd3 100644 --- a/Source/Swig/swigtree.h +++ b/Source/Swig/swigtree.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigtree.h * @@ -51,3 +51,4 @@ extern void Swig_restore(Node *node); extern void Swig_print_tags(File *obj, Node *root); extern void Swig_print_tree(Node *obj); extern void Swig_print_node(Node *obj); +extern int Swig_print_quiet(int quiet); diff --git a/Source/Swig/swigwrap.h b/Source/Swig/swigwrap.h index e44cb5344..b584ca495 100644 --- a/Source/Swig/swigwrap.h +++ b/Source/Swig/swigwrap.h @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * swigwrap.h * diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index d3bc720ff..d39696f5b 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * symbol.c * diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c index e2162b7f1..438e8b73d 100644 --- a/Source/Swig/tree.c +++ b/Source/Swig/tree.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * tree.c * @@ -16,6 +16,20 @@ #include <stdarg.h> #include <assert.h> +static int debug_quiet = 0; + +/* ----------------------------------------------------------------------------- + * Swig_print_quiet() + * + * Set quiet mode when printing a parse tree node + * ----------------------------------------------------------------------------- */ + +int Swig_print_quiet(int quiet) { + int previous_quiet = debug_quiet; + debug_quiet = quiet; + return previous_quiet; +} + /* ----------------------------------------------------------------------------- * Swig_print_tags() * @@ -66,33 +80,42 @@ static void print_indent(int l) { void Swig_print_node(Node *obj) { Iterator ki; Node *cobj; + List *keys = Keys(obj); print_indent(0); - Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj); - ki = First(obj); - while (ki.key) { - String *k = ki.key; - if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) || - (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) { + if (debug_quiet) + Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj)); + else + Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj); + + SortList(keys, 0); + ki = First(keys); + while (ki.item) { + String *k = ki.item; + DOH *value = Getattr(obj, k); + if (Equal(k, "nodeType") || (*(Char(k)) == '$')) { + /* Do nothing */ + } else if (debug_quiet && (Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") || + Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") || + Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) { /* Do nothing */ - } else if (Cmp(k, "kwargs") == 0 || Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0 || - Cmp(k, "pattern") == 0 || Cmp(k, "templateparms") == 0 || Cmp(k, "throws") == 0) { + } else if (Equal(k, "kwargs") || Equal(k, "parms") || Equal(k, "wrap:parms") || Equal(k, "pattern") || Equal(k, "templateparms") || Equal(k, "throws")) { print_indent(2); /* Differentiate parameter lists by displaying within single quotes */ - Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(Getattr(obj, k))); + Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(value)); } else { DOH *o; const char *trunc = ""; print_indent(2); - if (DohIsString(Getattr(obj, k))) { - o = Str(Getattr(obj, k)); + if (DohIsString(value)) { + o = Str(value); if (Len(o) > 80) { trunc = "..."; } Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc); Delete(o); } else { - Printf(stdout, "%-12s - %p\n", k, Getattr(obj, k)); + Printf(stdout, "%-12s - %p\n", k, value); } } ki = Next(ki); @@ -107,6 +130,7 @@ void Swig_print_node(Node *obj) { print_indent(1); Printf(stdout, "\n"); } + Delete(keys); } /* ----------------------------------------------------------------------------- @@ -261,12 +285,16 @@ int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_ * ns - namespace for the view name for saving any attributes under * n - node * ... - list of attribute names of type char* - * This method checks that the attribute names exist in the node n and asserts if - * not. Assert will only occur unless the attribute is optional. An attribute is - * optional if it is prefixed by ?, eg "?value". If the attribute name is prefixed - * by * or ?, eg "*value" then a copy of the attribute is saved. The saved - * attributes will be restored on a subsequent call to Swig_restore(). All the - * saved attributes are saved in the view namespace (prefixed by ns). + * + * An attribute is optional if it is prefixed by ?, eg "?value". All + * non-optional attributes are checked for on node n and if any do not exist + * SWIG exits with a fatal error. + * + * If the attribute name is prefixed by * or ?, eg "*value" then a copy of the + * attribute is saved. The saved attributes will be restored on a subsequent + * call to Swig_restore(). All the saved attributes are saved in the view + * namespace (prefixed by ns). + * * This function can be called more than once with different namespaces. * ----------------------------------------------------------------------------- */ @@ -291,7 +319,7 @@ void Swig_require(const char *ns, Node *n, ...) { obj = Getattr(n, name); if (!opt && !obj) { Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", name, nodeType(n)); - assert(obj); + Exit(EXIT_FAILURE); } if (!obj) obj = DohNone; diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 3273c19db..f0dee59d9 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * typemap.c * @@ -151,7 +151,7 @@ static void set_typemap(const SwigType *type, Hash **tmhash) { * Initialize the typemap system * ----------------------------------------------------------------------------- */ -void Swig_typemap_init() { +void Swig_typemap_init(void) { typemaps = NewHash(); } @@ -511,7 +511,12 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { if (sm) { /* Got a typemap. Need to only merge attributes for methods that match our signature */ Iterator ki; + Hash *deferred_add; match = 1; + + /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm. + * Create a temporary hash of typemaps to add immediately after. */ + deferred_add = NewHash(); for (ki = First(sm); ki.key; ki = Next(ki)) { /* Check for a signature match with the source signature */ if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) { @@ -521,34 +526,36 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { Replace(nkey, ssig, dsig, DOH_REPLACE_ANY); /* Make sure the typemap doesn't already exist in the target map */ - oldm = Getattr(tm, nkey); if (!oldm || (!Getattr(tm, "code"))) { String *code; - ParmList *locals; - ParmList *kwargs; Hash *sm1 = ki.item; code = Getattr(sm1, "code"); - locals = Getattr(sm1, "locals"); - kwargs = Getattr(sm1, "kwargs"); if (code) { - String *src_str = ParmList_str_multibrackets(src); - String *dest_str = ParmList_str_multibrackets(dest); - String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str); - Replace(nkey, dsig, "", DOH_REPLACE_ANY); Replace(nkey, "tmap:", "", DOH_REPLACE_ANY); - typemap_register(nkey, dest, code, locals, kwargs, source_directive); - - Delete(source_directive); - Delete(dest_str); - Delete(src_str); + Setattr(deferred_add, nkey, sm1); } } Delete(nkey); } } + + /* After assembling the key/item pairs, add the resulting typemaps */ + for (ki = First(deferred_add); ki.key; ki = Next(ki)) { + Hash *sm1 = ki.item; + String *src_str = ParmList_str_multibrackets(src); + String *dest_str = ParmList_str_multibrackets(dest); + String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str); + + typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive); + + Delete(source_directive); + Delete(dest_str); + Delete(src_str); + } + Delete(deferred_add); } Delete(ssig); Delete(dsig); @@ -1443,7 +1450,6 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No * ie, not use the typemap code, otherwise both f and actioncode must be non null. */ if (actioncode) { const String *result_equals = NewStringf("%s = ", Swig_cresult_name()); - clname = Copy(actioncode); /* check that the code in the typemap can be used in this optimal way. * The code should be in the form "result = ...;\n". We need to extract * the "..." part. This may not be possible for various reasons, eg @@ -1451,22 +1457,17 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No * hack and circumvents the normal requirement for a temporary variable * to hold the result returned from a wrapped function call. */ - if (Strncmp(clname, result_equals, 9) == 0) { - int numreplacements = Replace(clname, result_equals, "", DOH_REPLACE_ID_BEGIN); - if (numreplacements == 1) { - numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END); - if (numreplacements == 1) { - if (Strchr(clname, ';') == 0) { - lname = clname; - actioncode = 0; - optimal_substitution = 1; - } - } - } - } - if (!optimal_substitution) { + if (Strncmp(actioncode, result_equals, Len(result_equals)) == 0 && + Strchr(actioncode, ';') == Char(actioncode) + Len(actioncode) - 2 && + Char(actioncode)[Len(actioncode) - 1] == '\n') { + clname = NewStringWithSize(Char(actioncode) + Len(result_equals), + Len(actioncode) - Len(result_equals) - 2); + lname = clname; + actioncode = 0; + optimal_substitution = 1; + } else { Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node)); - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", clname); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", actioncode); delete_optimal_attribute = 1; } } else { @@ -2090,6 +2091,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper Printf(stdout, "Swig_typemap_attach_parms: embedded\n"); #endif if (already_substituting < 10) { + char* found_colon; already_substituting++; if ((in_typemap_search_multi == 0) && typemap_search_debug) { String *dtypemap = NewString(dollar_typemap); @@ -2097,7 +2099,15 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper Printf(stdout, " Containing: %s\n", dtypemap); Delete(dtypemap); } - Swig_typemap_attach_parms(tmap_method, to_match_parms, f); + found_colon = Strchr(tmap_method, ':'); + if (found_colon) { + /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */ + String *temp_tmap_method = NewStringWithSize(Char(tmap_method), (int)(found_colon - Char(tmap_method))); + Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, NULL); + Delete(temp_tmap_method); + } else { + Swig_typemap_attach_parms(tmap_method, to_match_parms, f); + } already_substituting--; /* Look for the typemap code */ @@ -2160,7 +2170,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper * Display all typemaps * ----------------------------------------------------------------------------- */ -void Swig_typemap_debug() { +void Swig_typemap_debug(void) { int nesting_level = 2; Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n"); Swig_print(typemaps, nesting_level); diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index 3e376fb07..581362520 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * typeobj.c * @@ -443,8 +443,8 @@ SwigType *SwigType_del_pointer(SwigType *t) { c++; } if (strncmp(c, "p.", 2)) { - printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n"); - abort(); + printf("Fatal error: SwigType_del_pointer applied to non-pointer.\n"); + Exit(EXIT_FAILURE); } Delslice(t, 0, (int)((c - s) + 2)); return t; @@ -486,9 +486,10 @@ SwigType *SwigType_add_reference(SwigType *t) { SwigType *SwigType_del_reference(SwigType *t) { char *c = Char(t); - int check = strncmp(c, "r.", 2); - assert(check == 0); - (void)check; + if (strncmp(c, "r.", 2)) { + printf("Fatal error: SwigType_del_reference applied to non-reference.\n"); + Exit(EXIT_FAILURE); + } Delslice(t, 0, 2); return t; } @@ -522,9 +523,10 @@ SwigType *SwigType_add_rvalue_reference(SwigType *t) { SwigType *SwigType_del_rvalue_reference(SwigType *t) { char *c = Char(t); - int check = strncmp(c, "z.", 2); - assert(check == 0); - (void)check; + if (strncmp(c, "z.", 2)) { + fprintf(stderr, "Fatal error: SwigType_del_rvalue_reference() applied to non-rvalue-reference.\n"); + Exit(EXIT_FAILURE); + } Delslice(t, 0, 2); return t; } @@ -727,9 +729,10 @@ SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) { SwigType *SwigType_del_array(SwigType *t) { char *c = Char(t); - int check = strncmp(c, "a(", 2); - assert(check == 0); - (void)check; + if (strncmp(c, "a(", 2)) { + fprintf(stderr, "Fatal error: SwigType_del_array() applied to non-array.\n"); + Exit(EXIT_FAILURE); + } Delslice(t, 0, element_size(c)); return t; } @@ -822,8 +825,10 @@ void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) { char *c = Char(t); start = c; - if (strncmp(c, "a(", 2)) - abort(); + if (strncmp(c, "a(", 2)) { + fprintf(stderr, "Fatal error: SwigType_array_type applied to non-array.\n"); + Exit(EXIT_FAILURE); + } while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) { c = strchr(c, '.'); @@ -915,8 +920,8 @@ SwigType *SwigType_pop_function(SwigType *t) { c = Char(t); } if (strncmp(c, "f(", 2)) { - printf("Fatal error. SwigType_pop_function applied to non-function.\n"); - abort(); + fprintf(stderr, "Fatal error. SwigType_pop_function applied to non-function.\n"); + Exit(EXIT_FAILURE); } g = SwigType_pop(t); if (f) diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index d6d6bcc88..74384f860 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * typesys.c * @@ -180,7 +180,7 @@ int Swig_value_wrapper_mode(int mode) { } -static void flush_cache() { +static void flush_cache(void) { typedef_resolve_cache = 0; typedef_all_cache = 0; typedef_qualified_cache = 0; @@ -188,7 +188,7 @@ static void flush_cache() { /* Initialize the scoping system */ -void SwigType_typesystem_init() { +void SwigType_typesystem_init(void) { if (global_scope) Delete(global_scope); if (scopes) @@ -407,7 +407,7 @@ void SwigType_using_scope(Typetab *scope) { * table for the scope that was popped off. * ----------------------------------------------------------------------------- */ -Typetab *SwigType_pop_scope() { +Typetab *SwigType_pop_scope(void) { Typetab *t, *old = current_scope; t = Getattr(current_scope, "parent"); if (!t) @@ -1702,7 +1702,9 @@ void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr cl if (t) { char *ct = Char(t); - if (strchr(ct, '<') && !(strstr(ct, "<("))) { + const char *lt = strchr(ct, '<'); + /* Allow for `<<` operator in constant expression for array size. */ + if (lt && lt[1] != '(' && lt[1] != '<') { Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t); assert(0); } @@ -1974,6 +1976,7 @@ void SwigType_inherit_equiv(File *out) { Hash *sub; Hash *rh; List *rlist; + List *r_resolved_sorted_keys; Iterator rk, bk, ck; if (!conversions) @@ -1981,10 +1984,12 @@ void SwigType_inherit_equiv(File *out) { if (!subclass) subclass = NewHash(); - rk = First(r_resolved); - while (rk.key) { + r_resolved_sorted_keys = SortedKeys(r_resolved, Strcmp); + rk = First(r_resolved_sorted_keys); + while (rk.item) { + List *sub_sorted_keys; /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */ - base = SwigType_base(rk.key); + base = SwigType_base(rk.item); /* Check to see whether the base is recorded in the subclass table */ sub = Getattr(subclass, base); Delete(base); @@ -1995,28 +2000,29 @@ void SwigType_inherit_equiv(File *out) { /* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */ - rh = Getattr(r_resolved, rk.key); + rh = Getattr(r_resolved, rk.item); rlist = NewList(); for (ck = First(rh); ck.key; ck = Next(ck)) { Append(rlist, ck.key); } - /* Printf(stdout,"rk.key = '%s'\n", rk.key); + /* Printf(stdout,"rk.item = '%s'\n", rk.item); Printf(stdout,"rh = %p '%s'\n", rh,rh); */ - bk = First(sub); - while (bk.key) { - prefix = SwigType_prefix(rk.key); - Append(prefix, bk.key); + sub_sorted_keys = SortedKeys(sub, Strcmp); + bk = First(sub_sorted_keys); + while (bk.item) { + prefix = SwigType_prefix(rk.item); + Append(prefix, bk.item); /* Printf(stdout,"set %p = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */ mprefix = SwigType_manglestr(prefix); Setattr(rh, mprefix, prefix); - mkey = SwigType_manglestr(rk.key); + mkey = SwigType_manglestr(rk.item); ckey = NewStringf("%s+%s", mprefix, mkey); if (!Getattr(conversions, ckey)) { String *convname = NewStringf("%sTo%s", mprefix, mkey); - String *lkey = SwigType_lstr(rk.key, 0); + String *lkey = SwigType_lstr(rk.item, 0); String *lprefix = SwigType_lstr(prefix, 0); - Hash *subhash = Getattr(sub, bk.key); + Hash *subhash = Getattr(sub, bk.item); String *convcode = Getattr(subhash, "convcode"); if (convcode) { char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */ @@ -2077,29 +2083,13 @@ void SwigType_inherit_equiv(File *out) { Delete(mkey); bk = Next(bk); } + Delete(sub_sorted_keys); rk = Next(rk); Delete(rlist); } + Delete(r_resolved_sorted_keys); } -/* Helper function to sort the mangled list */ -static int SwigType_compare_mangled(const DOH *a, const DOH *b) { - return strcmp((char *) Data(a), (char *) Data(b)); -} - -/* ----------------------------------------------------------------------------- - * SwigType_get_sorted_mangled_list() - * - * Returns the sorted list of mangled type names that should be exported into the - * wrapper file. - * ----------------------------------------------------------------------------- */ -List *SwigType_get_sorted_mangled_list() { - List *l = Keys(r_mangled); - SortList(l, SwigType_compare_mangled); - return l; -} - - /* ----------------------------------------------------------------------------- * SwigType_type_table() * @@ -2126,22 +2116,22 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { /*#define DEBUG 1*/ #ifdef DEBUG Printf(stdout, "---r_mangled---\n"); - Printf(stdout, "%s\n", r_mangled); + Swig_print(r_mangled, 2); Printf(stdout, "---r_resolved---\n"); - Printf(stdout, "%s\n", r_resolved); + Swig_print(r_resolved, 2); Printf(stdout, "---r_ltype---\n"); - Printf(stdout, "%s\n", r_ltype); + Swig_print(r_ltype, 2); Printf(stdout, "---subclass---\n"); - Printf(stdout, "%s\n", subclass); + Swig_print(subclass, 2); Printf(stdout, "---conversions---\n"); - Printf(stdout, "%s\n", conversions); + Swig_print(conversions, 2); Printf(stdout, "---r_clientdata---\n"); - Printf(stdout, "%s\n", r_clientdata); + Swig_print(r_clientdata, 2); #endif table = NewStringEmpty(); @@ -2155,12 +2145,10 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n"); - mangled_list = SwigType_get_sorted_mangled_list(); + mangled_list = SortedKeys(r_mangled, Strcmp); for (ki = First(mangled_list); ki.item; ki = Next(ki)) { List *el; Iterator ei; - SwigType *lt; - SwigType *rt = 0; String *nt; String *ln; String *rn; @@ -2168,8 +2156,12 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { Hash *lthash; Iterator ltiter; Hash *nthash; + String *cast_temp_conv; + String *resolved_lstr = 0; + List *ntlist; cast_temp = NewStringEmpty(); + cast_temp_conv = NewStringEmpty(); Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL); Append(table_list, ki.item); @@ -2185,8 +2177,8 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { nthash = NewHash(); ltiter = First(lthash); while (ltiter.key) { - lt = ltiter.key; - rt = SwigType_typedef_resolve_all(lt); + SwigType *lt = ltiter.key; + SwigType *rt = SwigType_typedef_resolve_all(lt); /* we save the original type and the fully resolved version */ ln = SwigType_lstr(lt, 0); rn = SwigType_lstr(rt, 0); @@ -2196,6 +2188,12 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { Setattr(nthash, rn, "1"); Setattr(nthash, ln, "1"); } + if (!resolved_lstr) { + resolved_lstr = Copy(rn); + } else if (Len(rn) < Len(resolved_lstr)) { + Delete(resolved_lstr); + resolved_lstr = Copy(rn); + } if (SwigType_istemplate(rt)) { String *dt = Swig_symbol_template_deftype(rt, 0); String *dn = SwigType_lstr(dt, 0); @@ -2205,33 +2203,50 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { Delete(dt); Delete(dn); } + Delete(rt); + Delete(rn); + Delete(ln); ltiter = Next(ltiter); } /* now build nt */ - ltiter = First(nthash); + ntlist = SortedKeys(nthash, Strcmp); + ltiter = First(ntlist); nt = 0; - while (ltiter.key) { - if (nt) { - Printf(nt, "|%s", ltiter.key); - } else { - nt = NewString(ltiter.key); + while (ltiter.item) { + if (!Equal(resolved_lstr, ltiter.item)) { + if (nt) { + Printf(nt, "|%s", ltiter.item); + } else { + nt = NewString(ltiter.item); + } } ltiter = Next(ltiter); } + /* Last in list is a resolved type used by SWIG_TypePrettyName. + * There can be more than one resolved type and the chosen one is simply the + * shortest in length, arguably the most user friendly/readable. */ + if (nt) { + Printf(nt, "|%s", resolved_lstr); + } else { + nt = NewString(resolved_lstr); + } + Delete(ntlist); Delete(nthash); + Delete(resolved_lstr); Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd); el = SwigType_equivalent_mangle(ki.item, 0, 0); + SortList(el, Strcmp); for (ei = First(el); ei.item; ei = Next(ei)) { String *ckey; String *conv; ckey = NewStringf("%s+%s", ei.item, ki.item); conv = Getattr(conversions, ckey); if (conv) { - Printf(cast_temp, " {&_swigt_%s, %s, 0, 0},", ei.item, conv); + Printf(cast_temp_conv, " {&_swigt_%s, %s, 0, 0},", ei.item, conv); } else { Printf(cast_temp, " {&_swigt_%s, 0, 0, 0},", ei.item); } @@ -2248,13 +2263,13 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) { } } Delete(el); - Printf(cast, "%s{0, 0, 0, 0}};\n", cast_temp); + Printf(cast, "%s%s{0, 0, 0, 0}};\n", cast_temp, cast_temp_conv); + Delete(cast_temp_conv); Delete(cast_temp); Delete(nt); - Delete(rt); } /* print the tables in the proper order */ - SortList(table_list, SwigType_compare_mangled); + SortList(table_list, Strcmp); i = 0; for (ki = First(table_list); ki.item; ki = Next(ki)) { Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++); diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c index 29a59cc49..6d8237245 100644 --- a/Source/Swig/wrapfunc.c +++ b/Source/Swig/wrapfunc.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * wrapfunc.c * @@ -27,7 +27,7 @@ static int Max_line_size = 128; Wrapper *NewWrapper(void) { Wrapper *w; - w = (Wrapper *) malloc(sizeof(Wrapper)); + w = (Wrapper *) Malloc(sizeof(Wrapper)); w->localh = NewHash(); w->locals = NewStringEmpty(); w->code = NewStringEmpty(); @@ -46,7 +46,7 @@ void DelWrapper(Wrapper *w) { Delete(w->locals); Delete(w->code); Delete(w->def); - free(w); + Free(w); } /* ----------------------------------------------------------------------------- |