mirror of https://github.com/swig/swig
Validate scopename in nspace feature
This commit is contained in:
parent
59827e7191
commit
e4795e9af0
|
@ -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 {};
|
||||
}
|
||||
}
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue