Merge branch 'RMemberListTrialSimplify2019'
* RMemberListTrialSimplify2019: ENH R abstract_access_runme ENH R accessor processing test Removed some remaining commented sections moved registration routine and use swig_name_get calling Swig_name_setget Used Swig_name_register so that Swig_name_wrapper produces the correct name without a separate replace call. Removed last instance of using Strcmp to check for a set/get method. Replaced with check for flag. Alternative version of using memberlist processing. This clarifies the logic within OutputMemberReferenceMethod by filtering the lists into classes, rather than doing it internally. Code isn't any shorter. commenting out unused code first pass at removing string comparisons for set/get methods trial changing member list processing
This commit is contained in:
commit
7648542775
2 changed files with 222 additions and 99 deletions
|
|
@ -36,11 +36,6 @@ static String * getRTypeName(SwigType *t, int *outCount = NULL) {
|
|||
if(Strncmp(b, "struct ", 7) == 0)
|
||||
Replace(b, "struct ", "", DOH_REPLACE_FIRST);
|
||||
|
||||
/* Printf(stdout, "<getRTypeName> %s,base = %s\n", t, b);
|
||||
for(i = 0; i < Len(els); i++)
|
||||
Printf(stdout, "%d) %s, ", i, Getitem(els,i));
|
||||
Printf(stdout, "\n"); */
|
||||
|
||||
for(i = 0; i < Len(els); i++) {
|
||||
String *el = Getitem(els, i);
|
||||
if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) {
|
||||
|
|
@ -56,13 +51,6 @@ static String * getRTypeName(SwigType *t, int *outCount = NULL) {
|
|||
Insert(tmp, 0, retName);
|
||||
return tmp;
|
||||
|
||||
/*
|
||||
if(count)
|
||||
return(b);
|
||||
|
||||
Delete(b);
|
||||
return(NewString(""));
|
||||
*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------
|
||||
|
|
@ -285,11 +273,16 @@ protected:
|
|||
int generateCopyRoutines(Node *n);
|
||||
int DumpCode(Node *n);
|
||||
|
||||
int OutputMemberReferenceMethod(String *className, int isSet, List *el, File *out);
|
||||
int OutputMemberReferenceMethod(String *className, int isSet,
|
||||
List *memberList, List *nameList,
|
||||
List *typeList, File *out);
|
||||
#if 0
|
||||
// not used
|
||||
int OutputArrayMethod(String *className, List *el, File *out);
|
||||
int OutputClassMemberTable(Hash *tb, File *out);
|
||||
int OutputClassMethodsTable(File *out);
|
||||
int OutputClassAccessInfo(Hash *tb, File *out);
|
||||
#endif
|
||||
|
||||
int defineArrayAccessors(SwigType *type);
|
||||
|
||||
|
|
@ -334,10 +327,14 @@ protected:
|
|||
|
||||
|
||||
void addAccessor(String *memberName, Wrapper *f,
|
||||
String *name, int isSet = -1);
|
||||
String *name, String *methodSetGet);
|
||||
|
||||
static int getFunctionPointerNumArgs(Node *n, SwigType *tt);
|
||||
|
||||
// filtering of class member lists by function type. Used in constructing accessors
|
||||
// are we allowed to use stl style functors to customise this?
|
||||
List* filterMemberList(List *class_member_function_types, List *class_member_other, String *R_MEMBER, bool equal);
|
||||
|
||||
protected:
|
||||
bool copyStruct;
|
||||
bool memoryProfile;
|
||||
|
|
@ -367,11 +364,20 @@ protected:
|
|||
String *member_name;
|
||||
String *class_name;
|
||||
|
||||
String *R_MEMBER_NORMAL;
|
||||
String *R_MEMBER_SET;
|
||||
String *R_MEMBER_GET;
|
||||
|
||||
int processing_class_member_function;
|
||||
List *class_member_functions;
|
||||
List *class_member_set_functions;
|
||||
|
||||
// List *class_member_functions;
|
||||
// List *class_member_set_functions;
|
||||
// Spread out the lists so that they are simpler to process
|
||||
// by storing the type of the method (i.e. set, get or nothing)
|
||||
// and having separate lists for name, membername and wrapper
|
||||
List *class_member_function_types;
|
||||
List *class_member_function_names;
|
||||
List *class_member_function_membernames;
|
||||
List *class_member_function_wrappernames;
|
||||
/* */
|
||||
Hash *ClassMemberTable;
|
||||
Hash *ClassMethodsTable;
|
||||
|
|
@ -429,9 +435,14 @@ R::R() :
|
|||
processing_member_access_function(0),
|
||||
member_name(0),
|
||||
class_name(0),
|
||||
R_MEMBER_NORMAL(NewString("normal")),
|
||||
R_MEMBER_SET(NewString("set")),
|
||||
R_MEMBER_GET(NewString("get")),
|
||||
processing_class_member_function(0),
|
||||
class_member_functions(0),
|
||||
class_member_set_functions(0),
|
||||
class_member_function_types(0),
|
||||
class_member_function_names(0),
|
||||
class_member_function_membernames(0),
|
||||
class_member_function_wrappernames(0),
|
||||
ClassMemberTable(0),
|
||||
ClassMethodsTable(0),
|
||||
SClassDefs(0),
|
||||
|
|
@ -510,7 +521,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
|
|||
SwigType *funcparams = SwigType_functionpointer_decompose(rettype);
|
||||
String *rtype = SwigType_str(rettype, 0);
|
||||
|
||||
// ParmList *parms = Getattr(n, "parms");
|
||||
// ParmList *parms = Getattr(n, "parms");
|
||||
// memory leak
|
||||
ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n);
|
||||
|
||||
|
|
@ -755,6 +766,8 @@ int R::top(Node *n) {
|
|||
Swig_register_filebyname("snamespace", s_namespace);
|
||||
Printf(s_namespace, "useDynLib(%s)\n", DllName);
|
||||
}
|
||||
// Register the naming functions
|
||||
Swig_name_register("wrapper", "R_swig_%f");
|
||||
|
||||
/* Associate the different streams with names so that they can be used in %insert directives by the
|
||||
typemap code. */
|
||||
|
|
@ -888,7 +901,33 @@ int R::DumpCode(Node *n) {
|
|||
}
|
||||
|
||||
|
||||
List *R::filterMemberList(List *class_member_types,
|
||||
List *class_member_other,
|
||||
String *R_MEMBER, bool equal) {
|
||||
// filters class_member_other based on whether corresponding elements of
|
||||
// class_member_function_types are equal or notequal to R_MEMBER
|
||||
List *CM = NewList();
|
||||
Iterator ftype, other;
|
||||
|
||||
for (ftype = First(class_member_types), other = First(class_member_other);
|
||||
ftype.item;
|
||||
ftype=Next(ftype), other=Next(other)) {
|
||||
// verbose, clean up later if the overall structure works
|
||||
if (equal) {
|
||||
if (ftype.item == R_MEMBER) {
|
||||
Append(CM, other.item);
|
||||
}
|
||||
} else {
|
||||
if (ftype.item != R_MEMBER) {
|
||||
Append(CM, other.item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(CM);
|
||||
}
|
||||
|
||||
# if 0
|
||||
// not called
|
||||
/* -------------------------------------------------------------
|
||||
* We may need to do more.... so this is left as a
|
||||
* stub for the moment.
|
||||
|
|
@ -975,9 +1014,6 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
|
|||
isSet = strcmp(ptr, "_set") == 0;
|
||||
}
|
||||
|
||||
// OutputArrayMethod(className, el, out);
|
||||
OutputMemberReferenceMethod(className, isSet, el, out);
|
||||
|
||||
if(outputNamespaceInfo)
|
||||
Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : "");
|
||||
}
|
||||
|
|
@ -988,6 +1024,8 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
|
|||
return n;
|
||||
}
|
||||
|
||||
// end not used
|
||||
#endif
|
||||
/* --------------------------------------------------------------
|
||||
* Write the methods for $ or $<- for accessing a member field in an
|
||||
* struct or union (or class).
|
||||
|
|
@ -1000,9 +1038,10 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
|
|||
* out - the stream where we write the code.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::OutputMemberReferenceMethod(String *className, int isSet,
|
||||
List *el, File *out) {
|
||||
int numMems = Len(el), j;
|
||||
int R::OutputMemberReferenceMethod(String *className, int isSet,
|
||||
List *memberList, List *nameList,
|
||||
List *typeList, File *out) {
|
||||
int numMems = Len(memberList), j;
|
||||
int varaccessor = 0;
|
||||
if (numMems == 0)
|
||||
return SWIG_OK;
|
||||
|
|
@ -1017,13 +1056,12 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
|
|||
|
||||
Node *itemList = NewHash();
|
||||
bool has_prev = false;
|
||||
for(j = 0; j < numMems; j+=3) {
|
||||
String *item = Getitem(el, j);
|
||||
String *dup = Getitem(el, j + 1);
|
||||
char *ptr = Char(dup);
|
||||
ptr = &ptr[Len(dup) - 3];
|
||||
for(j = 0; j < numMems; j++) {
|
||||
String *item = Getitem(memberList, j);
|
||||
String *dup = Getitem(nameList, j);
|
||||
String *setgetmethod = Getitem(typeList, j);
|
||||
|
||||
if (!strcmp(ptr, "get"))
|
||||
if (setgetmethod == R_MEMBER_GET)
|
||||
varaccessor++;
|
||||
|
||||
if (Getattr(itemList, item))
|
||||
|
|
@ -1053,30 +1091,20 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
|
|||
|
||||
if (!isSet && varaccessor > 0) {
|
||||
Printf(f->code, "%svaccessors = c(", tab8);
|
||||
int first = 1;
|
||||
for(j = 0; j < numMems; j+=3) {
|
||||
String *item = Getitem(el, j);
|
||||
String *dup = Getitem(el, j + 1);
|
||||
char *ptr = Char(dup);
|
||||
ptr = &ptr[Len(dup) - 3];
|
||||
bool first = true;
|
||||
for(j = 0; j < numMems; j++) {
|
||||
String *item = Getitem(memberList, j);
|
||||
String *setgetmethod = Getitem(typeList, j);
|
||||
|
||||
if (!strcmp(ptr, "get")) {
|
||||
// Check the type here instead of the name
|
||||
if (setgetmethod == R_MEMBER_GET) {
|
||||
Printf(f->code, "%s'%s'", first ? "" : ", ", item);
|
||||
first = 0;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
Printf(f->code, ");\n");
|
||||
}
|
||||
|
||||
|
||||
/* Printv(f->code, tab8,
|
||||
"idx = pmatch(name, names(accessorFuns))\n",
|
||||
tab8,
|
||||
"if(is.na(idx)) {\n",
|
||||
tab8, tab4,
|
||||
"stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className,
|
||||
": fields are \", paste(names(accessorFuns), sep = \", \")",
|
||||
")", "\n}\n", NIL); */
|
||||
Printv(f->code, ";", tab8,
|
||||
"idx = pmatch(name, names(accessorFuns));\n",
|
||||
tab8,
|
||||
|
|
@ -1123,6 +1151,8 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// not used
|
||||
/* -------------------------------------------------------------
|
||||
* Write the methods for [ or [<- for accessing a member field in an
|
||||
* struct or union (or class).
|
||||
|
|
@ -1162,6 +1192,7 @@ int R::OutputArrayMethod(String *className, List *el, File *out) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
* Called when a enumeration is to be processed.
|
||||
|
|
@ -1207,7 +1238,6 @@ int R::enumDeclaration(Node *n) {
|
|||
Printf(enum_def_calls, "defineEnumeration(\"%s\",\n .values=c(%s))\n\n", ename, enum_values);
|
||||
Delete(enum_values);
|
||||
Delete(ename);
|
||||
//Delete(symname);
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -1335,31 +1365,21 @@ int R::variableWrapper(Node *n) {
|
|||
* --------------------------------------------------------------*/
|
||||
|
||||
void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
|
||||
int isSet) {
|
||||
if(isSet < 0) {
|
||||
int n = Len(name);
|
||||
char *ptr = Char(name);
|
||||
if (n>4) {
|
||||
isSet = Strcmp(NewString(&ptr[n-4]), "_set") == 0;
|
||||
}
|
||||
String *methodSetGet) {
|
||||
|
||||
if (!class_member_function_names) {
|
||||
class_member_function_names = NewList();
|
||||
class_member_function_membernames = NewList();
|
||||
class_member_function_wrappernames = NewList();
|
||||
class_member_function_types = NewList();
|
||||
}
|
||||
|
||||
List *l = isSet ? class_member_set_functions : class_member_functions;
|
||||
|
||||
if(!l) {
|
||||
l = NewList();
|
||||
if(isSet)
|
||||
class_member_set_functions = l;
|
||||
else
|
||||
class_member_functions = l;
|
||||
}
|
||||
|
||||
Append(l, memberName);
|
||||
Append(l, name);
|
||||
|
||||
Append(class_member_function_types, methodSetGet);
|
||||
Append(class_member_function_names, name);
|
||||
Append(class_member_function_membernames, memberName);
|
||||
|
||||
String *tmp = NewString("");
|
||||
Wrapper_print(wrapper, tmp);
|
||||
Append(l, tmp);
|
||||
Append(class_member_function_wrappernames, tmp);
|
||||
// if we could put the wrapper in directly: Append(l, Copy(sfun));
|
||||
if (debugMode)
|
||||
Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
|
||||
|
|
@ -1390,11 +1410,6 @@ List * R::Swig_overload_rank(Node *n,
|
|||
c = Getattr(c,"sym:nextSibling");
|
||||
continue;
|
||||
}
|
||||
/* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
|
||||
c = Getattr(c,"sym:nextSibling");
|
||||
continue;
|
||||
} */
|
||||
|
||||
/* Make a list of all the declarations (methods) that are overloaded with
|
||||
* this one particular method name */
|
||||
|
||||
|
|
@ -1815,14 +1830,9 @@ int R::functionWrapper(Node *n) {
|
|||
/* Add the name of this member to a list for this class_name.
|
||||
We will dump all these at the end. */
|
||||
|
||||
int n = Len(iname);
|
||||
char *ptr = Char(iname);
|
||||
bool isSet(0);
|
||||
if (n > 4) isSet = Strcmp(NewString(&ptr[n-4]), "_set") == 0;
|
||||
bool isSet(GetFlag(n, "memberset"));
|
||||
|
||||
|
||||
String *tmp = NewString("");
|
||||
Printf(tmp, "%s_%s", class_name, isSet ? "set" : "get");
|
||||
String *tmp = NewString(isSet ? Swig_name_set(NSPACE_TODO, class_name) : Swig_name_get(NSPACE_TODO, class_name));
|
||||
|
||||
List *memList = Getattr(ClassMemberTable, tmp);
|
||||
if(!memList) {
|
||||
|
|
@ -1839,7 +1849,7 @@ int R::functionWrapper(Node *n) {
|
|||
int nargs;
|
||||
|
||||
String *wname = Swig_name_wrapper(iname);
|
||||
Replace(wname, "_wrap", "R_swig", DOH_REPLACE_FIRST);
|
||||
|
||||
if(overname)
|
||||
Append(wname, overname);
|
||||
Setattr(n,"wrap:name", wname);
|
||||
|
|
@ -1859,11 +1869,6 @@ int R::functionWrapper(Node *n) {
|
|||
if(!isVoidReturnType)
|
||||
addCopyParam = addCopyParameter(rtype);
|
||||
|
||||
|
||||
// Can we get the nodeType() of the type node! and see if it is a struct.
|
||||
// int addCopyParam = SwigType_isclass(rtype);
|
||||
|
||||
// if(addCopyParam)
|
||||
if (debugMode)
|
||||
Printf(stdout, "Adding a .copy argument to %s for %s = %s\n",
|
||||
iname, type, addCopyParam ? "yes" : "no");
|
||||
|
|
@ -2261,7 +2266,13 @@ int R::functionWrapper(Node *n) {
|
|||
Would like to be able to do this so that we can potentially insert
|
||||
*/
|
||||
if(processing_member_access_function || processing_class_member_function) {
|
||||
addAccessor(member_name, sfun, iname);
|
||||
String *method_type = R_MEMBER_NORMAL;
|
||||
if (GetFlag(n, "memberset")) {
|
||||
method_type = R_MEMBER_SET;
|
||||
} else if (GetFlag(n, "memberget")) {
|
||||
method_type = R_MEMBER_GET;
|
||||
}
|
||||
addAccessor(member_name, sfun, iname, method_type);
|
||||
}
|
||||
|
||||
if (Getattr(n, "sym:overloaded") &&
|
||||
|
|
@ -2456,19 +2467,57 @@ int R::classDeclaration(Node *n) {
|
|||
|
||||
|
||||
// OutputArrayMethod(name, class_member_functions, sfile);
|
||||
#if 0
|
||||
// RJB - this bit will need to change
|
||||
if (class_member_functions)
|
||||
OutputMemberReferenceMethod(name, 0, class_member_functions, sfile);
|
||||
if (class_member_set_functions)
|
||||
OutputMemberReferenceMethod(name, 1, class_member_set_functions, sfile);
|
||||
#else
|
||||
if (class_member_function_types) {
|
||||
|
||||
if(class_member_functions) {
|
||||
Delete(class_member_functions);
|
||||
class_member_functions = NULL;
|
||||
}
|
||||
if(class_member_set_functions) {
|
||||
Delete(class_member_set_functions);
|
||||
class_member_set_functions = NULL;
|
||||
}
|
||||
// collect the "set" methods
|
||||
List *class_set_membernames = filterMemberList(class_member_function_types,
|
||||
class_member_function_membernames, R_MEMBER_SET, true);
|
||||
List *class_set_functionnames = filterMemberList(class_member_function_types,
|
||||
class_member_function_names, R_MEMBER_SET, true);
|
||||
// this one isn't used - collecting to keep code simpler
|
||||
List *class_set_functiontypes = filterMemberList(class_member_function_types,
|
||||
class_member_function_types, R_MEMBER_SET, true);
|
||||
|
||||
// collect the others
|
||||
List *class_other_membernames = filterMemberList(class_member_function_types,
|
||||
class_member_function_membernames, R_MEMBER_SET, false);
|
||||
List *class_other_functionnames = filterMemberList(class_member_function_types,
|
||||
class_member_function_names, R_MEMBER_SET, false);
|
||||
List *class_other_functiontypes = filterMemberList(class_member_function_types,
|
||||
class_member_function_types, R_MEMBER_SET, false);
|
||||
|
||||
if (Len(class_other_membernames) > 0) {
|
||||
OutputMemberReferenceMethod(name, 0, class_other_membernames, class_other_functionnames, class_other_functiontypes, sfile);
|
||||
}
|
||||
if (Len(class_set_membernames) > 0) {
|
||||
OutputMemberReferenceMethod(name, 1, class_set_membernames, class_set_functionnames, class_set_functiontypes, sfile);
|
||||
}
|
||||
Delete(class_set_membernames);
|
||||
Delete(class_set_functionnames);
|
||||
Delete(class_set_functiontypes);
|
||||
Delete(class_other_membernames);
|
||||
Delete(class_other_functionnames);
|
||||
Delete(class_other_functiontypes);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (class_member_function_types) {
|
||||
Delete(class_member_function_types);
|
||||
class_member_function_types = NULL;
|
||||
Delete(class_member_function_names);
|
||||
class_member_function_names = NULL;
|
||||
Delete(class_member_function_membernames);
|
||||
class_member_function_membernames = NULL;
|
||||
Delete(class_member_function_wrappernames);
|
||||
class_member_function_wrappernames = NULL;
|
||||
}
|
||||
if (Getattr(n, "has_destructor")) {
|
||||
Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue