Validate scopename in nspace feature

This commit is contained in:
William S Fulton 2024-05-26 19:32:54 +01:00
parent 59827e7191
commit e4795e9af0
6 changed files with 110 additions and 27 deletions

View File

@ -0,0 +1,29 @@
%module xxx
// Bad names for %nspacemove
%nspacemove(2) AA::BB::Bad1;
%nspacemove(1abc) AA::BB::Bad2;
%nspacemove(abc.def) AA::BB::Bad3;
%nspacemove(0gh::ij) AA::BB::Bad4;
%nspacemove(kl::1mn) AA::BB::Bad5;
%nspacemove(kl::mn<int>) AA::BB::Bad6;
// Good names for %nspacemove
%nspacemove(_aaa::_bbb) AA::BB::Good1;
%nspacemove(_ccc::_ddd::_eee) AA::BB::Good2;
%nspacemove(_1ccc::_2ddd::_3eee) AA::BB::Good3;
namespace AA {
namespace BB {
struct Bad1 {};
struct Bad2 {};
struct Bad3 {};
struct Bad4 {};
struct Bad5 {};
struct Bad6 {};
struct Good1 {};
struct Good2 {};
struct Good3 {};
}
}

View File

@ -0,0 +1,6 @@
cpp_nspacemove_bad.i:18: Error: '2' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:19: Error: '1abc' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:20: Error: 'abc.def' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:21: Error: '0gh::ij' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:22: Error: 'kl::1mn' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:23: Error: 'kl::mn<int>' is not a valid identifier for nspace.

View File

@ -352,40 +352,46 @@ class TypePass:private Dispatcher {
String *nspace_setting(Node *n, Node *outer) {
String *nssymname_new = nssymname;
String *feature_nspace = GetFlagAttr(n, "feature:nspace");
int valid = feature_nspace ? Equal(feature_nspace, "1") || Swig_scopename_isvalid(feature_nspace) : 1;
String *nspace = Copy(feature_nspace);
Replaceall(nspace, "::", ".");
if (outer) {
// Nested class or enum in a class
String *outer_nspace = Getattr(outer, "sym:nspace");
//Printf(stdout, "nspace value %s on %s\n", outer_nspace, Getattr(n, "name"));
String *nspace_attribute = Getattr(n, "feature:nspace");;
bool warn = false;
if (outer_nspace) {
if (Equal(nspace_attribute, "0")) {
warn = true;
} else if (nspace && !(Equal(nspace, "1") || Equal(nspace, outer_nspace))) {
if (valid) {
if (outer) {
// Nested class or enum in a class
String *outer_nspace = Getattr(outer, "sym:nspace");
String *nspace_attribute = Getattr(n, "feature:nspace");
bool warn = false;
if (outer_nspace) {
if (Equal(nspace_attribute, "0")) {
warn = true;
} else if (nspace && !(Equal(nspace, "1") || Equal(nspace, outer_nspace))) {
warn = true;
}
} else if (nspace) {
warn = true;
}
} else if (nspace) {
warn = true;
if (warn) {
String *outer_nspace_feature = Copy(outer_nspace);
Replaceall(outer_nspace_feature, ".", "::");
Swig_warning(WARN_TYPE_NSPACE_SETTING, Getfile(n), Getline(n), "Ignoring nspace setting (%s) for '%s',\n", nspace_attribute, Swig_name_decl(n));
Swig_warning(WARN_TYPE_NSPACE_SETTING, Getfile(outer), Getline(outer), "as it conflicts with the nspace setting (%s) for outer class '%s'.\n", outer_nspace, Swig_name_decl(outer));
}
Setattr(n, "sym:nspace", outer_nspace);
} else {
if (nspace) {
if (Equal(nspace, "1")) {
if (nssymname)
Setattr(n, "sym:nspace", nssymname);
} else {
Setattr(n, "sym:nspace", nspace);
nssymname_new = nspace;
}
}
}
if (warn) {
Swig_warning(WARN_TYPE_NSPACE_SETTING, Getfile(n), Getline(n), "Ignoring nspace setting (%s) for '%s',\n", nspace_attribute, Swig_name_decl(n));
Swig_warning(WARN_TYPE_NSPACE_SETTING, Getfile(outer), Getline(outer), "as it conflicts with the nspace setting (%s) for outer class '%s'.\n", outer_nspace, Swig_name_decl(outer));
}
Setattr(n, "sym:nspace", outer_nspace);
//Printf(stdout, "setting nspace %s on %s to %s\n", outer_nspace, Getattr(n, "name"), outer_nspace);
} else {
if (nspace) {
if (Equal(nspace, "1")) {
if (nssymname)
Setattr(n, "sym:nspace", nssymname);
} else {
Setattr(n, "sym:nspace", nspace);
nssymname_new = nspace;
}
}
Swig_error(Getfile(n), Getline(n), "'%s' is not a valid identifier for nspace.\n", feature_nspace);
}
Delete(nspace);
return nssymname_new;
}

View File

@ -984,6 +984,28 @@ List *Swig_scopename_tolist(const String *s) {
return scopes;
}
/* -----------------------------------------------------------------------------
* Swig_scopename_isvalid()
*
* Checks that s is a valid scopename (C++ namespace scope)
* ----------------------------------------------------------------------------- */
int Swig_scopename_isvalid(const String *s) {
List *scopes = Swig_scopename_tolist(s);
int valid = 0;
Iterator si;
for (si = First(scopes); si.item; si = Next(si)) {
String *subscope = si.item;
valid = subscope && Len(subscope) > 0;
if (valid)
valid = Swig_symbol_isvalid(subscope);
if (!valid)
break;
}
return valid;
}
/* -----------------------------------------------------------------------------
* Swig_scopename_check()
*

View File

@ -252,6 +252,7 @@ extern "C" {
extern ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl);
extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope);
extern SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab);
extern int Swig_symbol_isvalid(const String *s);
/* --- Parameters and Parameter Lists --- */
@ -332,6 +333,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern String *Swig_scopename_suffix(const String *s);
extern List *Swig_scopename_tolist(const String *s);
extern int Swig_scopename_check(const String *s);
extern int Swig_scopename_isvalid(const String *s);
extern String *Swig_string_lower(String *s);
extern String *Swig_string_upper(String *s);
extern String *Swig_string_title(String *s);

View File

@ -2223,3 +2223,21 @@ SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) {
}
return value;
}
/* -----------------------------------------------------------------------------
* Swig_symbol_isvalid()
*
* Checks that s is a valid C symbol
* ----------------------------------------------------------------------------- */
int Swig_symbol_isvalid(const String *s) {
int valid = 0;
const char *c = Char(s);
if (c) {
valid = isalpha((int)*c) || (*c == '_');
while (valid && *++c) {
valid = isalnum((int)*c) || (*c == '_');
}
}
return valid;
}