|
|
Todo for R-SWIG
To Add/Fix
-
Check cplusplus example with static field total enabled. - Seems to work
- Check abstractClass.i and the generated code to see if we get constructor routines for the virtual class.
- We automatically get no constructor, but we do get a delete method for Abstract.
The attribute "abstract" is set on the class node. (Doesn't print nicely.) The attribute is a List.
-
Inheritance for C++. If a method m() is defined in a derived class B of a class A, have the $ operator call that of A to get the appropriate inheritance. - Done - Add accessor for static fields in C++ class.
- Really want to do this as something like Abc::field where Abc is the class and field is a dynamic accessor. Wait until we have class-level slots in S4.
- Separate the set and get accessor functions so that the general accessor $ and $&- can work on the correct versions. Done.
-
- Still need to separate accessors to fields and those of methods so can have a proper [[ operator.
- Polymorphism for C++. Figure out the best way to deal with it in the R interface.
-
- Why are we defining setMethod()s for all accessors.
- All to do with if overname is defined. Need to "refine" this.
-
- We should use sym:name for the routines to support %rename directives.
-
-
- Why is typedefHandler not invoked when typedef a union inline,
-
- e. typedef union { ... } U;?
- It needs the name, i.e. union _U { .... } before it will call typedefHandler.
Is there a way we can easily identify these.
classDeclaration may have all the information to indicate that
we should call typedefHandler() ourselves.
unnamed is set, storage is typedef and tdname is set to U.
-
- Need to consolidate all the places we get the name of a new
class and where we strip the "struct " away. There are currently
7 instances of the word "struct" in the code.
-
getRTypeName and getRClassName should be somewhat more related.
defineArrayAccessors should use one of these.
-
- Empty class name for union slot.
- union.i
Fixed now, but with added code in that location (~ 1680).
Uses getRClassName.
But the result is a class that is never defined - U.
Should we return URef and define that or should we
define a class in R for representing a union U.
-
- Crash of SWIG in union.i when we inline the union definition within the struct.
-
This happens in classDeclaration(). The value of c in the for
loop which is an insert nodeType gives rise to an elType of
NULL. If we don't try to process this, the SWIG just generates
accessors to the elements of the union as
<container name>_<field name of
union>_<union's field name>,
e.g.
A_u_i and A_u_d
So we no longer process this.
It would be nice to be able to recognize this and make
suitable adjustments to the $ or [[ methods for the
structure, and possibly the names of the accessor functions.
-
- Allow unions to be copied by reference, and only reference.
-
-
- For C++ classes, add the collection methods for the $ and also the [[.
-
Done by adding a memberfunctionHandler() method to the class R
and setting a flag to say we are in the state of processing a
member function. Then, the resulting call to functionWrapper()
ends up adding to the class_member_functions list/hashtable.
It adds the function name and the definition of the function.
We can then add this to the $ operator for that class.
Overloading will cause us some additional problems.
-
Support overloading of C++ methods. - Done
-
- add .cxx to the list of supported extensions in R.
-
-
- Finish off the processing of the opaque for structs.
- Now ignoring member accessor function generation.
Don't support the full copy if there is no representation.
-
-
Are we generating classses for typedefs? e.g. see simpleStruct and the typedef for typedef B C; Yes. Code has been changed to coerce all types to base typedef
-
- Add finalizers via typemaps and via an R function to access
the C code.
- Can always do this directly. No real extra machinery necessary,
at present, I think.
-
- Make the .copy use the enumeration SCopyReferences? and
have 3 different levels of copying
none, copy, or DEEP.
- Change the default for .copy = FALSE to DEEP or TRUE
when we are dealing with return an array (not a reference)
for a variable.
-
-
- Extra arguments to routines to control whether the result is
copied or passed by reference.
Deep and shallow copies of a struct, etc.
Add extra arguments to R function and C routines.
Use the C code when possible - we have both R and C implementations.
-
If the result is a struct or pointer to a struct. If it
is a struct copy means return as is. Otherwise, make a
reference to it and leave it around. (Have to prerserve
the C object.)
If it is a pointer, copy means deep copy. Otherwise,
pass back reference.
- Want to check that the class is defined in R.
- Get the right default value for the new target object.
- Check the source type is not "opaque".
-
- Make certain the classes, etc. in defineArrayAccessors go into
the NAMESPACE as necessary.
-
-
- Get the name for R_swig_copy_BarRef_to_C right.
Should it have a Ref or not.
- simpleArray.i and Bar is an example
-
- Deal with the VIRTUAL class in ExternalReference?.
- If the VIRTUAL is there, we lose the ref slot in the derived
types!
-
- Look into dynamic variables for setting and getting C-level variables.
-
-
- Examples: cddb.i, suffix trees, image files, network data.
- Higher level: apply methods for looping over a disc.
-
- The bars_set in simpleArray.i.
- Works for list(BarRef?, BarRef?)
See simpleArray_tests.S
Like to get to work for list(Bar, Bar), etc.
-
- Mechanism for turning an *Ref into an *Array
- Basically, we just don't know the length. So it has to be
done manually.
-
- Deal with the const's in the cddb code and the warnings from the compiler.
-
-
- Define methods for SWIGFunction class.
- i.e. help and print methods.
-
- For function pointers, if we have an scoerceout
for any of the parameters or an scoercein
for the return type, create a local
function that is called first that does these and
then calls the user-supplied function.
- e.g. from routine.h, we would want to end up with
do_op =
function(a, b, op) {
...
if(is.function(op)) {
userFunc = op
op = function(a, b) {
ans = userFunc(a, b)
as.numeric(ans)
}
}
...
}
-
- Work on the cddb_log to make the function pointer stuff robust.
- Types for declaration of arguments now using SwigType?_str()
so turn into real C types.
Works. Code in ~/Projects/libcddb-1.2.0 with an extra argument
to take user defined data. Fix and pass back a patch.
-
- Add an opaque directive to declare that a struct, union or
class
should not be processed at the element level and no interface
should be generated to access these elements. Rather, deal only
with references/pointers.
-
Add an "opaque" directive to treat a struct as being "opaque",
-
- e. so we don't generate the set and get methods for the elements and the copy routines.
Can add something like
%feature("opaque", "yes") getARef ;
to a .i file to indicate that the feature opaque should have a
value yes for the routine getARef.
If we do this for
%feature("opaque", "yes") struct B ;
it doesn't show up on the node for classDeclaration.
Nor its parent node.
The problem is that we have a syntax error in the .i file
because of this.
If I put a typedef there rather than struct B {... }
and refer to the typedef, then all is well.
Appears that if we drop the struct in struct C, all is well.
But what if we have something actually typed as C,
-
- e. struct C and a regular C (via an existing typedef).
-
- How do we get 5.4.2 of SWIG Basics to work for us and get
around the "assignment to read-only value" coming from assigning
a value to a struct.
-
Is this still an issue?
-
- Unions.
- Mostly same as structs and the code works as is. Test!
Can't really do the copy thing to and from R since
we don't know which field is active.
Need a hint.
-
- watch for virtual classes when dealing with
generating constructors, copying functions, etc.
-
-
- If the R/ directory exists, add R code to there.
- If man directory exists, add .Rd files there.
And src/
Make this portable.
Find out what support SWIG has for this.
-
- Run time checks for pointers using the EXTPTR tag.
- Mostly done in the regular runtime material from rrun.swg.
See how we can leverage SWIG's own runtime mechanism.
-
- See if we can find a way to do the vmaxget/set for the PROTECTs.
-
-
- see if there is a convenient way to differentiate between
primitive types and structures/classes/etc/ for SWIGTYPE.
-
-
- Exceptions.
-
-
- Output a log file of what was done, what warnings and what
errors we encountered.
-
-
- scoerce{in,out} maps. Documentation.
- typemap for coercing the result in R to a particular value,
i.e. postprocessing.
-
- Keywords such as next, while, for, and things like c() or t().
-
-
- Create Rd files.
- Read the "internal" ones from a file or directive.
Or more appropriately, dymamic help.
-
- Put the name on the OUTPUT argument.
- Can't really - they are all called OUTPUT.
Is there a way to add features?
Try to find a way so that when we use gcc and translation units
we will know the names.
S/Runtime Code
- defineEnumeration
- see srun.swg.
- ExternalReference?
- see srun.swg
-
- typechecking for S references.
- see srun.swg.
Check
-
- Check the redirects are sufficient.
- Check the wrapper one
-
- Add to usage/help for the module.
-
-
- More typemap checking for the output arguments.
-
-
- Add more to the rtype typemap as necessary
-
-
- What's happening with enums.
- Seem okay.
-
- Check on the NAMESPACE output.
-
C++
- Enhance and test with C++.
-
- overloading of methods
- allow
- Default arguments for S functions corresponding to C++ routines with default arguments.
-
Future
Handle the inheritance issue if B extends A and shares a method
foo(). Then, if we call B_foo() with an A, it should be okay.
(The correct methods will be called in the C++ code.)
Use this to generate the registration table for an existing R package.
Allow an OOP class extend a C++ class via functions as methods.
Done
-
- Need to handle the case where class B extends class A and we have
references to them and the external pointer test
says that we were expecting an instance of ARef.
Need to be able to allow this.
- We can defer to the S class system, checking in the S code.
If so, then add
is(x, 'ARef')
or
x = as(x, 'ARef')
If we do this, we want to see if the object extends
the appropriate base class.
We can do this in the resolveExternalRef.
Added a C++Reference class.
And now R_SWIG_resolveExternalRef() calls
R_SWIG_checkInherits() to see if the inheritance is appropriate.
Uses extends().
-
- Class/static methods in C++ classes.
-
- Have to change the names for S (s_Abc::total)
Done.
- Add S function.
Now appears in the code.
-
- Is the accessor method $ and $<- generated for structs and unions.
- Should be.
Yes.
-
- Make certain setClass() uses the base class.
- i.e. if B extends A in C++, then have BRef extend ARef.
See classDeclaration().
-
- Ending up with "struct ARef" rather than ARef for name of S class that extends ExternalReference?.
- in union.i
Happening in processType.
Filter the struct from the base type in getRTypeName().
-
- Two definitions for Union - URef
- See union.i
-
- Make certain to output the #ifdef __cplusplus extern "C" {
#endif
at the hed of runtime only after the runtime directive, or
alternatively when we first output our first drop of
code to f_runtime.
-
Just adjust the Swig_register_filebyname for "runtime" to go to
f_wrapper which is emitted before f_runtime.
-
-
dyn.load("simpleStruct.so"); source("simpleStruct_wrap.S")
a = new_A()
copyToR(a)
Error in getClass("intRefRef") : "intRefRef" is not a defined class
-
Need to define this when we see it in the membervariableHandler.
Done
But now we have to get rid of the errors in the
R_swig_copy_ARef_to_C
for the char * and int *.
We were pushing the SwigType?_push() twice now.
Need to make certain it is done once and only once.
-
- Add the scoercein and scheck for the value in the [<- array methods.
-
-
- new and delete for structs.
- And the correct methods for these.
e.g. create, delete/destroy generics with methods for these
types.
createNativeObject(name)
releaseNativeObject().
Add a finalizer when we call new.
-
- Explore different ways to deal with the .copy argument in the C
code for struct A [2] in the simpleArray.i code.
-
Could deal with a single loop here and put the copy
within the body to figure out what to do to generate the
individual element.
Need to put copy support into all the rest of the relevant
typemap entries.
-
- .copy argument for variable setting code in R
- Added BUT NOT USED/IMPLEMENTED. See addCopyParameter()
Checks if it is a reference.
Want something more discerning.
Delegating this to typemaps may be leaving it to
a place where we have less precise information,
-
- e. just SWIGTYPE .
-
- Arrays and pointers generally.
-
Need to know the length.
For fixed length e.g. int x[20] find out how to do that. $1_dim0.
For unknown length, need idioms in the typemap.
Array reference classes.
Define methods for [ and [<-. Use the set_item method in SWIG.
Define a SWIGArray class and create ones that extend this.
-
- Define classes for R for, e.g. double[]
struct A[].
-
Need to generate item accessors.
Does SWIG have anything for this ?
Basics work. Can set struct Bar in
simpleArray.i.
Can't do primitives quite yet.
Works now.
-
- simpleArray_test.S has problems for intRef not being defined
in arr = x()
-
-
- Fill in R_SWIG_create_SWIG_R_Array.
- Currently, just returning a basic list.
Works now to get the base type array.
Need to define new array classes in R
and also item accessors.
-
- When setting a method for accessing a variable, e.g. ui,
need to differentiate between set and get. Add an "ANY".
-
Also, make certain it is generic using if(isGeneric('')) setGeneric(....)
Where is this? I think it is no longer relevant.
Use obj$field rather than field(obj)
If we want the latter, generate it.
-
- For classes (structs and C++ classes),
-
- Deal with "struct Bar" in the typemap when we want BarRef?
Should we use the SWIGTYPE_... via the descriptor.
- Generate the representation
- Implement the R_SWIG_copy routines.
The type conversion of the data types.
Make certain to avoid circular references
i.e. a struct that contains a field that is an instance of
the same struct. Can't really happen. Just have to find
the pointer.
Get the replacement of the conversion of the to R field.
-
- Sort out the simpleArray for struct Bar.
-
scoercein code needs to refer to Bar not BarRef?.
May need a new type in the replacement/substitution,
$R_base
-
- Get the type declarations for structs correct in the swig_copy_$1_to_{R,C}.
- Getting closer. Need to ensure consistency.
Collection of tests needed to ensure that these are mapping to
the right things.
Look at the tests in the SWIG directories.
CHECK these eventhough this is in the Done.
-
- Put attributes on the functions giving the
argument and return types as S types.
- These can be used to do reflectance in R,
e.g. generating class definitions for
opaque data structures that have
..._get_[field name] methods.
Deal with enumeration values.
Need to handle the case of non-primitives.
Expand $R_class. Working now.
Have to find the correct node for which to do the lookup_new.
Working now.
Maybe WANT TO USE A DIFFERENT FORMAT, e.g. SwigType?_manglestr()
- Get the handling of char * in the copy_$1_to_R and to_C
to work the same way as they do in the regular typemap use.
-
- e. in the copy of structs to and from R. They are appearing as char, without the pointer.
- The issue may be that we are dealing with member elements in the structure that appear from their type as if they/it is just the base type. See basic.i for an example.
Are the typemaps being attached as they are in the functions,
e.g.
Swig_typemap_attach_parms("in", l, f);
Use SwigType?_push() to form the full type.
-
- Classes for the function pointers.
-
Added CRoutinePointer? to the available base classes.
Add a prototype to give the inputTypes and return Type.
Document as a feature.
-
- Differentiate between typedef and original in name if possible
- cddb_conn_t and cddb_conn_s where the latter is a struct and
the _t is the typedef.
Don't resolve the typedef.
SwigType?_manglestr() was doing the typedef_resolve.
We can use SwigType?_split() (a handy routine to know of)
and then work that way.
Now seems to be working.
-
- Ensure enums are defined, and working
- Use cddb_query to generate an error.
Perhaps don't call defineEnumeration, but just
do the setClass and assign() ourselves.
Okay now. Make certain that the Value is attached to the end in
the rules in r.swg when creating an EnumerationValue?.
Otherwise the class is not found.
-
- Make the .values be split across lines in the definition of an enumeration
- Avoid blowing the limit on the size of a line the parser can handle.
Fine now.
-
- R Functions as arguments when we expect a pointer to a routine.
- Callbacks.
See perl and python.
Generate proxy routine to convert values to S and pass them
to the function.
Need to make the S function that knows to use the specially
generated C routine.
And this has to be conditional on getting the
name of a routine, a NativeSymbolInfo?, or an R function.
-
- Get the right attributes on the parameters and type in the
function pointer.
- Possibly need to build our own node.
Just needed to add the lname attribute.
And to use the base of the swig type for the return type
rather than the entire node which contained the entire
function pointer and not the return value.
-
- Added a copyToC( Ref, Ref)
- This allows copyToC(new_A(), new_A())
so that we never need to bring the structs back to
R.
-
- Get simpleStruct to work from S.
- copyToR() and the other parts seem to work.
Need more interesting struct with references
- Allow people to put code into the spackageinitroutine.
-
Use %insert("sinitroutine").
-
- Default argument for obj in copyToC
-
- Generate code for NAMESPACE file.
- Mostly done. Added useDynLib
- Add options to control the output
- e.g. whether to emit the initialization routine for
registration,
Can also have a directive to insert additional code in there.
Have to be careful about declarations.
- Typechecking typemaps.
- Checking for NAs, etc.
See scheck typemap. Now included in the inputs.
-
- Map the names of the C primitives such as double, int, bool,
long, etc. to R data types so that they can be used in the
class representations for defining structs, unions, classes
in S4.
Use the "rtype" typemap and getRType() checks that.
-
- Add the case that there are output arguments but that there is
no return, it is void.
-
- Handle INOUT arguments.
- Do we get them almost for free from OUT arguments?
Pretty much. Just have to add typemaps.
- Multiple return values.
- i.e. output arguments.
Return list(.result = regular return value,
argName.M = value,
argName.N = value)
How do we get SWIG to recognize them.
int *OUTPUT.
Make the output.i in inst/examples/ work.
Works. Need to handle case of void return type.
And lots more typemap entries.
- Add usage output for the r module.
- i.e. help for the module.
Keep adding to it.
- No need to save the answer in the R function from the .Call()
if there is no conversion afterwards. So avoid the
ans = .Call(....)
ans
step and use just .Call(....)
to do the return in one step, avoiding the assignment.
(No compiler to help us out :-))
-
- Figure out how to get the replacements for the copy struct routines.
-
Swig_typemap_lookup_new()'s 3rd argument allows us to specify
the name of the replacement that we want.
Alternatively, we culd delegate the copying to R, i.e.
returning a reference but want the deep copy
means just call copyToR(ref) and that uses the get accessors for
each of the fields.
Similarly, if we want to pass an R object of class StructBar?
say to something that wants an struct Bar * (or event struct
Bar), then create one, and copy the entries using the set
accessors.
Now implemented as copyToR and copyToC.
- For variableWrapper(), if it is constant, just make
the get function the same as the name() function,
e.g. PiSquared? = PiSquared?_get
and don't bother defining a new one.
-
- Syntax error for _MyULong variable name in MyULong?_set in primitives.h
- Need to put s_ rather than just _ to avoid the conflict with
the C variable as R doesn't want a variable name to start with '_'.
- Get the name of the header file right.
- And make it available to the directives.
Can avoid this if we just use strings rather than files and then
Dump() at the end in the correct order.
Done. Now we don't generate the header or the class file.
- Output a header file giving the declarations of what we generate.
- Need this as we refer to routines before they are declared.
s_header in C code. Accessible in directives via %insert("header").
Get the name right.
- Add the runtime S code to the sfile.
- Use the %Rruntime "filename" directive.
- For an enumeration value being returned, call
makeEnumerationValue() but give it the definition of the
enumeration in the call, i.e. a global variable that gives
{name, value} pairs for each element.
- This would avoid having to lookup the definition in R.
This is an efficiency issue so low priority.
- Add information about the name (via $1_name in the "in"
typemap), position (index = $argnum) of the argument and
the routine being called when reporting error messages about, e.g.
NULL pointers or incorrect tags for externalptrs.
- Can't get the name of the routine from the typemap but when we
raise an exception, it will be in the error message.
Also, we can get that information from some compilers.
- In variable setting routines, need a different name for the parameter.
- Should we change the names of the arguments regardless to s_<name>...
If no name is given, make one up in a consistent manner - s_arg<n>.
If we makeup names ourselves, does this conflict with the
information in the typemaps and what is substituted in $1_...
- Enumeration that is not typedef'ed, but is named should be handled.
- Enum without a typedef are processed in constantWrapper.
and typdef..
We are using the name now rather than the typedef name
(tdname).
Perhaps define it for both, or allow a vector of names for the
enum.
defineEnumeration(c("Sex", "Gender"))
How this is handled - i.e. via aliases or not - is
up to us later on.
- Why are the unsigned int not being used from the typemap "scoercein".
- 2 words. But still should work.... See java.swg.
Was working. But there was no name on the parameter, just its type!
- Insert Rdefines.h into the wrapper code.
- Where is the only issue.
Do it in the rrun.swg? When does this get pulled in?
Via the %runtime in r.swg!
- Get the literal material to be included in the file into the file.
- Make certain all the redirections/Swig_register_byfilename()
are done.
- vmaxget and set around the .Call routines.
-
-
Allow the result of the .Call() to be stored and converted to
a different R object.
e.g. GtkWidget? and getting its classes.
See the scoerceout maps.
- Output the command line information into the generate S file(s).
-
- Fix the "Unknown target 'runtime' for %insert directive".
- Done now. Needed to redirect "runtime" output to /dev/null.
- For the constants, move the conversion code to the configuration files.
- i.e. out of the C++ code.
- Figure out the naming scheme to use for struct Bar, Bar, etc.
-
The value of the mangle field may work - struct ABC and typdef
struct ABC S both map to "_ABC".
Similarly, both have a descriptor SWIGTYPE_ABC.
We probably want S extends (SWIGTYPE)_ABC or to have a
virtual class as a parent, e.g. _ABC and StructABC? and S as
derived classes.
How does Perl, Python, Java do it?
Build it ourselves. SWIG does this so there may not be any
magical one-liner.
|