Runtime tables deterministic ordering (4)

Output C/C++ type strings (| separated) in swig_type_info tables in
fixed order. The types are output in alphabetically sorted order,
with an exception. The final type is a fully resolved type, but
does not necessarily include default template parameters.
This type is the one used by SWIG_TypePrettyName which is commonly
used to display a type when the wrong type is passed in as a
parameter.

Previously the order was not very deterministic due to the use of
internal hash tables which do not have an ordering guarantee.
This commit is contained in:
William S Fulton 2022-09-26 18:14:19 +01:00
commit 15b2ec53e3
3 changed files with 48 additions and 20 deletions

View file

@ -7,6 +7,13 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress) Version 4.1.0 (in progress)
=========================== ===========================
2022-09-29: wsfulton
#2303 Type tables are now output in a fixed order whereas previously
the order may change with any minor input code change. This shouldn't
affect users except SWIG_TypePrettyName may output a different C/C++
typedef to a type - it's used mostly for showing errors when the type
passed to a function is wrong.
2022-09-29: olly 2022-09-29: olly
[PHP] Dynamic class properties are no longer supported by default. [PHP] Dynamic class properties are no longer supported by default.

View file

@ -358,9 +358,9 @@ SWIG_TypeName(const swig_type_info *ty) {
SWIGRUNTIME const char * SWIGRUNTIME const char *
SWIG_TypePrettyName(const swig_type_info *type) { SWIG_TypePrettyName(const swig_type_info *type) {
/* The "str" field contains the equivalent pretty names of the /* The "str" field contains the equivalent pretty names of the
type, separated by vertical-bar characters. We choose type, separated by vertical-bar characters. Choose the last
to print the last name, as it is often (?) the most name. It should be the most specific; a fully resolved name
specific. */ but not necessarily with default template parameters expanded. */
if (!type) return NULL; if (!type) return NULL;
if (type->str != NULL) { if (type->str != NULL) {
const char *last_name = type->str; const char *last_name = type->str;

View file

@ -2136,22 +2136,22 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
/*#define DEBUG 1*/ /*#define DEBUG 1*/
#ifdef DEBUG #ifdef DEBUG
Printf(stdout, "---r_mangled---\n"); Printf(stdout, "---r_mangled---\n");
Printf(stdout, "%s\n", r_mangled); Swig_print(r_mangled, 2);
Printf(stdout, "---r_resolved---\n"); Printf(stdout, "---r_resolved---\n");
Printf(stdout, "%s\n", r_resolved); Swig_print(r_resolved, 2);
Printf(stdout, "---r_ltype---\n"); Printf(stdout, "---r_ltype---\n");
Printf(stdout, "%s\n", r_ltype); Swig_print(r_ltype, 2);
Printf(stdout, "---subclass---\n"); Printf(stdout, "---subclass---\n");
Printf(stdout, "%s\n", subclass); Swig_print(subclass, 2);
Printf(stdout, "---conversions---\n"); Printf(stdout, "---conversions---\n");
Printf(stdout, "%s\n", conversions); Swig_print(conversions, 2);
Printf(stdout, "---r_clientdata---\n"); Printf(stdout, "---r_clientdata---\n");
Printf(stdout, "%s\n", r_clientdata); Swig_print(r_clientdata, 2);
#endif #endif
table = NewStringEmpty(); table = NewStringEmpty();
@ -2169,8 +2169,6 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
for (ki = First(mangled_list); ki.item; ki = Next(ki)) { for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
List *el; List *el;
Iterator ei; Iterator ei;
SwigType *lt;
SwigType *rt = 0;
String *nt; String *nt;
String *ln; String *ln;
String *rn; String *rn;
@ -2179,6 +2177,8 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Iterator ltiter; Iterator ltiter;
Hash *nthash; Hash *nthash;
String *cast_temp_conv; String *cast_temp_conv;
String *resolved_lstr = 0;
List *ntlist;
cast_temp = NewStringEmpty(); cast_temp = NewStringEmpty();
cast_temp_conv = NewStringEmpty(); cast_temp_conv = NewStringEmpty();
@ -2197,8 +2197,8 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
nthash = NewHash(); nthash = NewHash();
ltiter = First(lthash); ltiter = First(lthash);
while (ltiter.key) { while (ltiter.key) {
lt = ltiter.key; SwigType *lt = ltiter.key;
rt = SwigType_typedef_resolve_all(lt); SwigType *rt = SwigType_typedef_resolve_all(lt);
/* we save the original type and the fully resolved version */ /* we save the original type and the fully resolved version */
ln = SwigType_lstr(lt, 0); ln = SwigType_lstr(lt, 0);
rn = SwigType_lstr(rt, 0); rn = SwigType_lstr(rt, 0);
@ -2208,6 +2208,12 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Setattr(nthash, rn, "1"); Setattr(nthash, rn, "1");
Setattr(nthash, ln, "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)) { if (SwigType_istemplate(rt)) {
String *dt = Swig_symbol_template_deftype(rt, 0); String *dt = Swig_symbol_template_deftype(rt, 0);
String *dn = SwigType_lstr(dt, 0); String *dn = SwigType_lstr(dt, 0);
@ -2217,22 +2223,38 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Delete(dt); Delete(dt);
Delete(dn); Delete(dn);
} }
Delete(rt);
Delete(rn);
Delete(ln);
ltiter = Next(ltiter); ltiter = Next(ltiter);
} }
/* now build nt */ /* now build nt */
ltiter = First(nthash); ntlist = sorted_list_from_hash(nthash);
ltiter = First(ntlist);
nt = 0; nt = 0;
while (ltiter.key) { while (ltiter.item) {
if (nt) { if (!Equal(resolved_lstr, ltiter.item)) {
Printf(nt, "|%s", ltiter.key); if (nt) {
} else { Printf(nt, "|%s", ltiter.item);
nt = NewString(ltiter.key); } else {
nt = NewString(ltiter.item);
}
} }
ltiter = Next(ltiter); 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(nthash);
Delete(resolved_lstr);
Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd); Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
@ -2265,7 +2287,6 @@ void SwigType_emit_type_table(File *f_forward, File *f_table) {
Delete(cast_temp_conv); Delete(cast_temp_conv);
Delete(cast_temp); Delete(cast_temp);
Delete(nt); Delete(nt);
Delete(rt);
} }
/* print the tables in the proper order */ /* print the tables in the proper order */
SortList(table_list, compare_strings); SortList(table_list, compare_strings);