Merge branch 'REnums2018'
* REnums2018: Fix R return by C++11 const ref enum classes Remove unused code in r.cxx extra doc on anonymous enums ENH: FIX: references to enums now functioning DOC: Extended documentation on enumeration support in R FIX: Corrected path to output from R tests Reformat comments in R module ENH: Run test for enum_thorough in R Code style changes post review ENH: R Module: Enumerations with values set by calls to C code, allowing arbitarily complex value expressions. Setting enum values with calls to the C code.
This commit is contained in:
commit
cfa7a4d4d0
7 changed files with 875 additions and 291 deletions
|
|
@ -189,9 +189,48 @@ of the proxy class baggage you see in other languages.
|
|||
|
||||
|
||||
<p>
|
||||
enumerations are characters which are then converted back and forth to
|
||||
ints before calling the C routines. All of the enumeration code is
|
||||
done in R.
|
||||
R doesn't have a native enumeration type. Enumerations are represented
|
||||
as character strings in R, with calls to R functions that convert back
|
||||
and forth between integers.
|
||||
|
||||
The details of enumeration names and contents are stored in hidden R
|
||||
environments, which are named according the the enumeration name - for
|
||||
example, an enumeration colour:
|
||||
<div class="code"><pre>
|
||||
enum colour { red=-1, blue, green = 10 };
|
||||
</pre></div>
|
||||
|
||||
will be initialized by the following call in R:
|
||||
<div class="code"><pre>
|
||||
defineEnumeration("_colour",
|
||||
.values=c("red" = .Call('R_swig_colour_red_get',FALSE, PACKAGE='enum_thorough'),
|
||||
"blue" = .Call('R_swig_colour_blue_get',FALSE, PACKAGE='enum_thorough'),
|
||||
"green" = .Call('R_swig_colour_green_get',FALSE, PACKAGE='enum_thorough')))
|
||||
|
||||
</pre></div>
|
||||
|
||||
which will create an environment named <tt>.__E___colour</tt>. The enumeration
|
||||
values are initialised via calls to C/C++ code, allowing complex
|
||||
values for enumerations to be used. Calls to the C/C++ code require
|
||||
the compiled library to be loaded, so a <tt>delayedAssign</tt> is employed
|
||||
within <tt>defineEnumeration</tt> in order to allow the code to be easily used in R
|
||||
packages.
|
||||
|
||||
The user typically does not need to access the enumeration lookup
|
||||
functions or know the name of the enumeration type used by
|
||||
R. Attributes containing the type information are attached by swig to
|
||||
functions requiring enumeration arguments or returning enumeration
|
||||
values, and those attributes are used to identify and access the
|
||||
appropriate environments and thus translate between characters
|
||||
and integers.
|
||||
|
||||
The relevant functions, for debugging purposes, are <tt>enumToInteger</tt> and
|
||||
</tt>enumFromInteger</tt>.
|
||||
|
||||
Anonymous enumerations are ignored by the binding generation process,
|
||||
leaving no way of accessing the value of anonymous enumerations from R
|
||||
code.
|
||||
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ CPP_TEST_CASES += \
|
|||
# arithmetic expressions
|
||||
|
||||
FAILING_CPP_TESTS = \
|
||||
enum_thorough \
|
||||
preproc_constants
|
||||
|
||||
FAILING_C_TESTS = \
|
||||
|
|
@ -64,7 +63,7 @@ include $(srcdir)/../common.mk
|
|||
# check for syntactic correctness
|
||||
run_testcase = \
|
||||
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PATH=.:"$$PATH" $(RUNTOOL) $(RUNR) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) || (cat $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)out ; false); \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PATH=.:"$$PATH" $(RUNTOOL) $(RUNR) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) || (cat ./$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)out ; false); \
|
||||
else \
|
||||
$(RUNTOOL) $(RUNR) ./$(SCRIPTPREFIX)$*$(WRAPSUFFIX) || (cat ./$(SCRIPTPREFIX)$*$(WRAPSUFFIX)out ; false); \
|
||||
fi
|
||||
|
|
@ -72,7 +71,7 @@ run_testcase = \
|
|||
run_multitestcase = \
|
||||
for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
|
||||
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PATH=.:"$$PATH" $(RUNTOOL) $(RUNR) $(SCRIPTDIR)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX) || (cat $(SCRIPTDIR)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX)out ; false); \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PATH=.:"$$PATH" $(RUNTOOL) $(RUNR) $(SCRIPTDIR)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX) || (cat ./$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX)out ; false); \
|
||||
else \
|
||||
$(RUNTOOL) $(RUNR) ./$(SCRIPTPREFIX)$${f}$(WRAPSUFFIX) || (cat ./$(SCRIPTPREFIX)$${f}$(WRAPSUFFIX)out ; false); \
|
||||
fi; \
|
||||
|
|
|
|||
452
Examples/test-suite/r/enum_thorough_runme.R
Normal file
452
Examples/test-suite/r/enum_thorough_runme.R
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
clargs <- commandArgs(trailing=TRUE)
|
||||
source(file.path(clargs[1], "unittest.R"))
|
||||
|
||||
dyn.load(paste("enum_thorough", .Platform$dynlib.ext, sep=""))
|
||||
source("enum_thorough.R")
|
||||
cacheMetaData(1)
|
||||
|
||||
## Anonymous enums are not wrapped by the R module
|
||||
##
|
||||
|
||||
# Colours - string interface, various function signatures
|
||||
unittest('red', colourTest1('red'))
|
||||
unittest('blue', colourTest1('blue'))
|
||||
unittest('green', colourTest1('green'))
|
||||
|
||||
|
||||
unittest('red', colourTest2('red'))
|
||||
unittest('blue', colourTest2('blue'))
|
||||
unittest('green', colourTest2('green'))
|
||||
|
||||
unittest('red', colourTest3('red'))
|
||||
unittest('blue', colourTest3('blue'))
|
||||
unittest('green', colourTest3('green'))
|
||||
|
||||
unittest('red', colourTest4('red'))
|
||||
unittest('blue', colourTest4('blue'))
|
||||
unittest('green', colourTest4('green'))
|
||||
|
||||
## Colours - underlying integers
|
||||
unittest(-1, enumToInteger('red', '_colour'))
|
||||
unittest(0, enumToInteger('blue', '_colour'))
|
||||
unittest(10, enumToInteger('green', '_colour'))
|
||||
|
||||
########
|
||||
## enum variable, wrapped as a function
|
||||
## Is initialization to 0 a "standard"
|
||||
myColour()
|
||||
|
||||
## Test setting and retrieving
|
||||
myColour('green')
|
||||
unittest('green', myColour())
|
||||
|
||||
########
|
||||
## SpeedClass
|
||||
|
||||
s <- SpeedClass()
|
||||
v <- "medium"
|
||||
unittest(v, s$speedTest1(v))
|
||||
unittest(v, s$speedTest2(v))
|
||||
unittest(v, s$speedTest3(v))
|
||||
unittest(v, s$speedTest4(v))
|
||||
unittest(v, s$speedTest5(v))
|
||||
unittest(v, s$speedTest6(v))
|
||||
unittest(v, s$speedTest7(v))
|
||||
unittest(v, s$speedTest8(v))
|
||||
|
||||
## speedTest methods not in the class
|
||||
|
||||
unittest(v, speedTest1(v))
|
||||
unittest(v, speedTest2(v))
|
||||
unittest(v, speedTest3(v))
|
||||
unittest(v, speedTest4(v))
|
||||
# enum reference
|
||||
unittest(v, speedTest5(v))
|
||||
|
||||
## member access
|
||||
s <- SpeedClass()
|
||||
unittest("slow", s$mySpeedtd1)
|
||||
# check integer value
|
||||
unittest(10, enumToInteger(s$mySpeedtd1, "_SpeedClass__speed"))
|
||||
# set and check
|
||||
s$mySpeedtd1 <- "lightning"
|
||||
unittest("lightning", s$mySpeedtd1)
|
||||
unittest(31, enumToInteger(s$mySpeedtd1, "_SpeedClass__speed"))
|
||||
|
||||
## Named anon - not wrapped nicely, but can be retrieved:
|
||||
|
||||
|
||||
unittest("NamedAnon2", namedanon_NamedAnon2_get())
|
||||
unittest(0, enumToInteger(namedanon_NamedAnon1_get(), "_namedanon"))
|
||||
unittest(1, enumToInteger(namedanon_NamedAnon2_get(), "_namedanon"))
|
||||
|
||||
## Twonames
|
||||
v <- "TwoNames1"
|
||||
unittest(v, twonamesTest1(v))
|
||||
unittest(v, twonamesTest2(v))
|
||||
unittest(v, twonamesTest3(v))
|
||||
unittest(33, enumToInteger("TwoNames3", "_twonamestag"))
|
||||
|
||||
tt <- TwoNamesStruct()
|
||||
v <- "TwoNamesStruct1"
|
||||
unittest(v, tt$twonamesTest1(v))
|
||||
unittest(v, tt$twonamesTest2(v))
|
||||
unittest(v, tt$twonamesTest3(v))
|
||||
## Try the wrong name
|
||||
unittest(TRUE, is.na(tt$twonamesTest3("TwoNames1")))
|
||||
|
||||
## Namedanonspace
|
||||
## can get the values
|
||||
|
||||
v <- namedanonspace_NamedAnonSpace2_get()
|
||||
unittest(v, namedanonspaceTest1(v))
|
||||
unittest(v, namedanonspaceTest2(v))
|
||||
unittest(v, namedanonspaceTest3(v))
|
||||
unittest(v, namedanonspaceTest4(v))
|
||||
|
||||
## scientists
|
||||
|
||||
tt <- TemplateClassInt()
|
||||
|
||||
g <- "galileo"
|
||||
unittest(g, tt$scientistsTest1(g))
|
||||
unittest(g, tt$scientistsTest2(g))
|
||||
unittest(g, tt$scientistsTest3(g))
|
||||
unittest(g, tt$scientistsTest4(g))
|
||||
unittest(g, tt$scientistsTest5(g))
|
||||
unittest(g, tt$scientistsTest6(g))
|
||||
unittest(g, tt$scientistsTest7(g))
|
||||
unittest(g, tt$scientistsTest8(g))
|
||||
unittest(g, tt$scientistsTest9(g))
|
||||
|
||||
## This one is commented out in csharp too
|
||||
## unittest(g, tt$scientistsTestA(g))
|
||||
unittest(g, tt$scientistsTestB(g))
|
||||
## This one is commented out in csharp too
|
||||
## unittest(g, tt$scientistsTestC(g))
|
||||
unittest(g, tt$scientistsTestD(g))
|
||||
unittest(g, tt$scientistsTestE(g))
|
||||
unittest(g, tt$scientistsTestF(g))
|
||||
unittest(g, tt$scientistsTestG(g))
|
||||
unittest(g, tt$scientistsTestH(g))
|
||||
unittest(g, tt$scientistsTestI(g))
|
||||
# enum reference
|
||||
unittest(g, tt$scientistsTestJ(g))
|
||||
|
||||
|
||||
unittest(g, scientistsTest1(g))
|
||||
unittest(g, scientistsTest2(g))
|
||||
unittest(g, scientistsTest3(g))
|
||||
unittest(g, scientistsTest4(g))
|
||||
unittest(g, scientistsTest5(g))
|
||||
unittest(g, scientistsTest6(g))
|
||||
unittest(g, scientistsTest7(g))
|
||||
## enum reference
|
||||
unittest(g, scientistsTest8(g))
|
||||
|
||||
tt <- TClassInt()
|
||||
b <- "bell"
|
||||
unittest(b, tt$scientistsNameTest1(b))
|
||||
unittest(b, tt$scientistsNameTest2(b))
|
||||
unittest(b, tt$scientistsNameTest3(b))
|
||||
unittest(b, tt$scientistsNameTest4(b))
|
||||
unittest(b, tt$scientistsNameTest5(b))
|
||||
unittest(b, tt$scientistsNameTest6(b))
|
||||
unittest(b, tt$scientistsNameTest7(b))
|
||||
unittest(b, tt$scientistsNameTest8(b))
|
||||
unittest(b, tt$scientistsNameTest9(b))
|
||||
|
||||
## This one is commented out in csharp too
|
||||
## unittest(b, tt$scientistsNameTestA(b))
|
||||
unittest(b, tt$scientistsNameTestB(b))
|
||||
## This one is commented out in csharp too
|
||||
## unittest(b, tt$scientistsNameTestC(b))
|
||||
unittest(b, tt$scientistsNameTestD(b))
|
||||
unittest(b, tt$scientistsNameTestE(b))
|
||||
unittest(b, tt$scientistsNameTestF(b))
|
||||
unittest(b, tt$scientistsNameTestG(b))
|
||||
unittest(b, tt$scientistsNameTestH(b))
|
||||
unittest(b, tt$scientistsNameTestI(b))
|
||||
|
||||
|
||||
unittest(b, tt$scientistsNameSpaceTest1(b))
|
||||
unittest(b, tt$scientistsNameSpaceTest2(b))
|
||||
unittest(b, tt$scientistsNameSpaceTest3(b))
|
||||
unittest(b, tt$scientistsNameSpaceTest4(b))
|
||||
unittest(b, tt$scientistsNameSpaceTest5(b))
|
||||
unittest(b, tt$scientistsNameSpaceTest6(b))
|
||||
unittest(b, tt$scientistsNameSpaceTest7(b))
|
||||
|
||||
unittest(g, tt$scientistsOtherTest1(g))
|
||||
unittest(g, tt$scientistsOtherTest2(g))
|
||||
unittest(g, tt$scientistsOtherTest3(g))
|
||||
unittest(g, tt$scientistsOtherTest4(g))
|
||||
unittest(g, tt$scientistsOtherTest5(g))
|
||||
unittest(g, tt$scientistsOtherTest6(g))
|
||||
unittest(g, tt$scientistsOtherTest7(g))
|
||||
|
||||
## Global
|
||||
unittest(b, scientistsNameTest1(b))
|
||||
unittest(b, scientistsNameTest2(b))
|
||||
unittest(b, scientistsNameTest3(b))
|
||||
unittest(b, scientistsNameTest4(b))
|
||||
unittest(b, scientistsNameTest5(b))
|
||||
unittest(b, scientistsNameTest6(b))
|
||||
unittest(b, scientistsNameTest7(b))
|
||||
|
||||
unittest(b, scientistsNameSpaceTest1(b))
|
||||
unittest(b, scientistsNameSpaceTest2(b))
|
||||
unittest(b, scientistsNameSpaceTest3(b))
|
||||
unittest(b, scientistsNameSpaceTest4(b))
|
||||
unittest(b, scientistsNameSpaceTest5(b))
|
||||
unittest(b, scientistsNameSpaceTest6(b))
|
||||
unittest(b, scientistsNameSpaceTest7(b))
|
||||
|
||||
unittest(b, scientistsNameSpaceTest8(b))
|
||||
unittest(b, scientistsNameSpaceTest9(b))
|
||||
unittest(b, scientistsNameSpaceTestA(b))
|
||||
unittest(b, scientistsNameSpaceTestB(b))
|
||||
unittest(b, scientistsNameSpaceTestC(b))
|
||||
unittest(b, scientistsNameSpaceTestD(b))
|
||||
unittest(b, scientistsNameSpaceTestE(b))
|
||||
unittest(b, scientistsNameSpaceTestF(b))
|
||||
unittest(b, scientistsNameSpaceTestG(b))
|
||||
unittest(b, scientistsNameSpaceTestH(b))
|
||||
unittest(b, scientistsNameSpaceTestI(b))
|
||||
unittest(b, scientistsNameSpaceTestJ(b))
|
||||
unittest(b, scientistsNameSpaceTestK(b))
|
||||
unittest(b, scientistsNameSpaceTestL(b))
|
||||
|
||||
## rename test
|
||||
v <- "eek"
|
||||
unittest(v, renameTest1(v))
|
||||
unittest(v, renameTest2(v))
|
||||
|
||||
## NewName
|
||||
N <- NewNameStruct()
|
||||
## Only half works:
|
||||
unittest("kerboom", NewNameStruct_bang_get())
|
||||
## Can't put in "bang" in the call
|
||||
## confirm with:
|
||||
## get(".__E___OldNameStruct__enumeration")
|
||||
|
||||
## TreeClass
|
||||
|
||||
T <- TreesClass()
|
||||
p <- "pine"
|
||||
|
||||
unittest(p, T$treesTest1(p))
|
||||
unittest(p, T$treesTest2(p))
|
||||
unittest(p, T$treesTest3(p))
|
||||
unittest(p, T$treesTest4(p))
|
||||
unittest(p, T$treesTest5(p))
|
||||
unittest(p, T$treesTest6(p))
|
||||
unittest(p, T$treesTest7(p))
|
||||
unittest(p, T$treesTest8(p))
|
||||
unittest(p, T$treesTest9(p))
|
||||
unittest(p, T$treesTestA(p))
|
||||
unittest(p, T$treesTestB(p))
|
||||
unittest(p, T$treesTestC(p))
|
||||
unittest(p, T$treesTestD(p))
|
||||
unittest(p, T$treesTestE(p))
|
||||
unittest(p, T$treesTestF(p))
|
||||
unittest(p, T$treesTestG(p))
|
||||
unittest(p, T$treesTestH(p))
|
||||
unittest(p, T$treesTestI(p))
|
||||
unittest(p, T$treesTestJ(p))
|
||||
unittest(p, T$treesTestK(p))
|
||||
unittest(p, T$treesTestL(p))
|
||||
unittest(p, T$treesTestM(p))
|
||||
unittest(p, T$treesTestN(p))
|
||||
unittest(p, T$treesTestO(p))
|
||||
|
||||
unittest(p, treesTest1(p))
|
||||
unittest(p, treesTest2(p))
|
||||
unittest(p, treesTest3(p))
|
||||
unittest(p, treesTest4(p))
|
||||
unittest(p, treesTest5(p))
|
||||
unittest(p, treesTest6(p))
|
||||
unittest(p, treesTest7(p))
|
||||
unittest(p, treesTest8(p))
|
||||
unittest(p, treesTest9(p))
|
||||
unittest(p, treesTestA(p))
|
||||
unittest(p, treesTestB(p))
|
||||
unittest(p, treesTestC(p))
|
||||
unittest(p, treesTestD(p))
|
||||
unittest(p, treesTestE(p))
|
||||
unittest(p, treesTestF(p))
|
||||
unittest(p, treesTestG(p))
|
||||
unittest(p, treesTestH(p))
|
||||
unittest(p, treesTestI(p))
|
||||
unittest(p, treesTestJ(p))
|
||||
unittest(p, treesTestK(p))
|
||||
unittest(p, treesTestL(p))
|
||||
unittest(p, treesTestM(p))
|
||||
unittest(p, treesTestO(p))
|
||||
unittest(p, treesTestP(p))
|
||||
unittest(p, treesTestQ(p))
|
||||
unittest(p, treesTestR(p))
|
||||
|
||||
## Hair
|
||||
h <- HairStruct()
|
||||
g <- "ginger"
|
||||
unittest(g, h$hairTest1(g))
|
||||
unittest(g, h$hairTest2(g))
|
||||
unittest(g, h$hairTest3(g))
|
||||
unittest(g, h$hairTest4(g))
|
||||
unittest(g, h$hairTest5(g))
|
||||
unittest(g, h$hairTest6(g))
|
||||
unittest(g, h$hairTest7(g))
|
||||
unittest(g, h$hairTest8(g))
|
||||
unittest(g, h$hairTest9(g))
|
||||
unittest(g, h$hairTestA(g))
|
||||
unittest(g, h$hairTestB(g))
|
||||
|
||||
r <- "red"
|
||||
unittest(r, h$colourTest1(r))
|
||||
unittest(r, h$colourTest2(r))
|
||||
|
||||
nmA <- "NamedAnon1"
|
||||
unittest(nmA, h$namedanonTest1(nmA))
|
||||
unittest("NamedAnonSpace2", h$namedanonspaceTest1("NamedAnonSpace2"))
|
||||
|
||||
f <- "fir"
|
||||
|
||||
unittest(f, h$treesGlobalTest1(f))
|
||||
unittest(f, h$treesGlobalTest2(f))
|
||||
unittest(f, h$treesGlobalTest3(f))
|
||||
unittest(f, h$treesGlobalTest4(f))
|
||||
|
||||
b <- "blonde"
|
||||
unittest(b, hairTest1(b))
|
||||
unittest(b, hairTest2(b))
|
||||
unittest(b, hairTest3(b))
|
||||
unittest(b, hairTest4(b))
|
||||
unittest(b, hairTest5(b))
|
||||
unittest(b, hairTest6(b))
|
||||
unittest(b, hairTest7(b))
|
||||
unittest(b, hairTest8(b))
|
||||
unittest(b, hairTest9(b))
|
||||
unittest(b, hairTestA(b))
|
||||
unittest(b, hairTestB(b))
|
||||
## enum reference
|
||||
unittest(b, hairTestC(b))
|
||||
unittest(b, hairTestA1(b))
|
||||
unittest(b, hairTestA2(b))
|
||||
unittest(b, hairTestA3(b))
|
||||
unittest(b, hairTestA4(b))
|
||||
unittest(b, hairTestA5(b))
|
||||
unittest(b, hairTestA6(b))
|
||||
unittest(b, hairTestA7(b))
|
||||
unittest(b, hairTestA8(b))
|
||||
unittest(b, hairTestA9(b))
|
||||
unittest(b, hairTestAA(b))
|
||||
unittest(b, hairTestAB(b))
|
||||
## enum reference
|
||||
unittest(b, hairTestAC(b))
|
||||
|
||||
unittest(b, hairTestB1(b))
|
||||
unittest(b, hairTestB2(b))
|
||||
unittest(b, hairTestB3(b))
|
||||
unittest(b, hairTestB4(b))
|
||||
unittest(b, hairTestB5(b))
|
||||
unittest(b, hairTestB6(b))
|
||||
unittest(b, hairTestB7(b))
|
||||
unittest(b, hairTestB8(b))
|
||||
unittest(b, hairTestB9(b))
|
||||
unittest(b, hairTestBA(b))
|
||||
unittest(b, hairTestBB(b))
|
||||
## enum reference
|
||||
unittest(b, hairTestBC(b))
|
||||
|
||||
f <- FirStruct()
|
||||
b <- "blonde"
|
||||
|
||||
unittest(b, f$hairTestFir1(b))
|
||||
unittest(b, f$hairTestFir2(b))
|
||||
unittest(b, f$hairTestFir3(b))
|
||||
unittest(b, f$hairTestFir4(b))
|
||||
unittest(b, f$hairTestFir5(b))
|
||||
unittest(b, f$hairTestFir6(b))
|
||||
unittest(b, f$hairTestFir7(b))
|
||||
unittest(b, f$hairTestFir8(b))
|
||||
unittest(b, f$hairTestFir9(b))
|
||||
unittest(b, f$hairTestFirA(b))
|
||||
|
||||
## Unnamed enum instance doesn't work
|
||||
## Wrapper set/get exists, but there's
|
||||
## no mapping between strings and integers
|
||||
GlobalInstance(1)
|
||||
unittest(1, GlobalInstance())
|
||||
|
||||
ii <- Instances()
|
||||
ii$MemberInstance <- 1
|
||||
unittest(1, ii$MemberInstance)
|
||||
|
||||
ii <- IgnoreTest()
|
||||
|
||||
## Testing integer values
|
||||
unittest(0, enumToInteger(IgnoreTest_ignoreA_zero_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(3, enumToInteger(IgnoreTest_ignoreA_three_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(10, enumToInteger(IgnoreTest_ignoreA_ten_get(), "_IgnoreTest__IgnoreA"))
|
||||
|
||||
unittest(11, enumToInteger(IgnoreTest_ignoreA_eleven_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(14, enumToInteger(IgnoreTest_ignoreA_fourteen_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(20, enumToInteger(IgnoreTest_ignoreA_twenty_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(30, enumToInteger(IgnoreTest_ignoreA_thirty_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(32, enumToInteger(IgnoreTest_ignoreA_thirty_two_get(), "_IgnoreTest__IgnoreA"))
|
||||
unittest(33, enumToInteger(IgnoreTest_ignoreA_thirty_three_get(), "_IgnoreTest__IgnoreA"))
|
||||
|
||||
unittest(11, enumToInteger(IgnoreTest_ignoreB_eleven_get(), "_IgnoreTest__IgnoreB"))
|
||||
unittest(12, enumToInteger(IgnoreTest_ignoreB_twelve_get(), "_IgnoreTest__IgnoreB"))
|
||||
unittest(31, enumToInteger(IgnoreTest_ignoreB_thirty_one_get(), "_IgnoreTest__IgnoreB"))
|
||||
unittest(32, enumToInteger(IgnoreTest_ignoreB_thirty_two_get(), "_IgnoreTest__IgnoreB"))
|
||||
unittest(41, enumToInteger(IgnoreTest_ignoreB_forty_one_get(), "_IgnoreTest__IgnoreB"))
|
||||
unittest(42, enumToInteger(IgnoreTest_ignoreB_forty_two_get(), "_IgnoreTest__IgnoreB"))
|
||||
|
||||
unittest(10, enumToInteger(IgnoreTest_ignoreC_ten_get(), "_IgnoreTest__IgnoreC"))
|
||||
unittest(12, enumToInteger(IgnoreTest_ignoreC_twelve_get(), "_IgnoreTest__IgnoreC"))
|
||||
unittest(30, enumToInteger(IgnoreTest_ignoreC_thirty_get(), "_IgnoreTest__IgnoreC"))
|
||||
unittest(32, enumToInteger(IgnoreTest_ignoreC_thirty_two_get(), "_IgnoreTest__IgnoreC"))
|
||||
unittest(40, enumToInteger(IgnoreTest_ignoreC_forty_get(), "_IgnoreTest__IgnoreC"))
|
||||
unittest(42, enumToInteger(IgnoreTest_ignoreC_forty_two_get(), "_IgnoreTest__IgnoreC"))
|
||||
|
||||
unittest(21, enumToInteger(IgnoreTest_ignoreD_twenty_one_get(), "_IgnoreTest__IgnoreD"))
|
||||
unittest(22, enumToInteger(IgnoreTest_ignoreD_twenty_two_get(), "_IgnoreTest__IgnoreD"))
|
||||
|
||||
unittest(0, enumToInteger(IgnoreTest_ignoreE_zero_get(), "_IgnoreTest__IgnoreE"))
|
||||
unittest(21, enumToInteger(IgnoreTest_ignoreE_twenty_one_get(), "_IgnoreTest__IgnoreE"))
|
||||
unittest(22, enumToInteger(IgnoreTest_ignoreE_twenty_two_get(), "_IgnoreTest__IgnoreE"))
|
||||
|
||||
## confirm that an ignore directive is followed:
|
||||
unittest(TRUE, is.na(ignoreCTest("ignoreC_eleven")))
|
||||
|
||||
|
||||
## repeat test
|
||||
unittest(1, enumToInteger(repeatTest("one"), "_RepeatSpace__repeat"))
|
||||
unittest(1, enumToInteger(repeatTest("initial"), "_RepeatSpace__repeat"))
|
||||
unittest(2, enumToInteger(repeatTest("two"), "_RepeatSpace__repeat"))
|
||||
unittest(3, enumToInteger(repeatTest("three"), "_RepeatSpace__repeat"))
|
||||
unittest(3, enumToInteger(repeatTest("llast"), "_RepeatSpace__repeat"))
|
||||
unittest(3, enumToInteger(repeatTest("end"), "_RepeatSpace__repeat"))
|
||||
|
||||
## Macro test - nothing in csharp
|
||||
## Note - this enum is set up with both entries the same
|
||||
## This means that mapping back from the integer value to the
|
||||
## string value isn't unique, so asking for "ABCD2" will return
|
||||
## a string of "ABCD"
|
||||
unittest("ABCD", enumWithMacroTest("ABCD"))
|
||||
|
||||
## Different types
|
||||
unittest(10, enumToInteger(differentTypesTest("typeint"), "_DifferentSpace__DifferentTypes"))
|
||||
unittest(0, enumToInteger(differentTypesTest("typeboolfalse"), "_DifferentSpace__DifferentTypes"))
|
||||
unittest(1, enumToInteger(differentTypesTest("typebooltrue"), "_DifferentSpace__DifferentTypes"))
|
||||
unittest(2, enumToInteger(differentTypesTest("typebooltwo"), "_DifferentSpace__DifferentTypes"))
|
||||
unittest(utf8ToInt('C'), enumToInteger(differentTypesTest("typechar"), "_DifferentSpace__DifferentTypes"))
|
||||
unittest(utf8ToInt('D'), enumToInteger(differentTypesTest("typedefaultint"), "_DifferentSpace__DifferentTypes"))
|
||||
unittest(utf8ToInt('A') + 1, enumToInteger(differentTypesTest("typecharcompound"), "_DifferentSpace__DifferentTypes"))
|
||||
|
||||
|
||||
## Global different types
|
||||
## Test uses an anonymous type so the string mapping
|
||||
## framework doesn't exist.
|
||||
|
|
@ -192,6 +192,11 @@ unsigned char *OUTPUT
|
|||
free($1);
|
||||
}
|
||||
|
||||
%typemap(in) const enum SWIGTYPE & ($*1_ltype temp)
|
||||
%{ temp = ($*1_ltype)INTEGER($input)[0];
|
||||
$1 = &temp; %}
|
||||
|
||||
%typemap(out) const enum SWIGTYPE & %{ $result = Rf_ScalarInteger((int)*$1); %}
|
||||
|
||||
%typemap(memberin) char[] %{
|
||||
if ($input) strcpy($1, $input);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
%typemap("rtype") enum SWIGTYPE * "character";
|
||||
%typemap("rtype") enum SWIGTYPE *const "character";
|
||||
%typemap("rtype") enum SWIGTYPE & "character";
|
||||
%typemap("rtype") const enum SWIGTYPE & "character";
|
||||
%typemap("rtype") enum SWIGTYPE && "character";
|
||||
%typemap("rtype") SWIGTYPE * "$R_class";
|
||||
%typemap("rtype") SWIGTYPE *const "$R_class";
|
||||
|
|
@ -86,9 +87,7 @@
|
|||
%typemap(scoercein) enum SWIGTYPE
|
||||
%{ $input = enumToInteger($input, "$R_class"); %}
|
||||
%typemap(scoercein) enum SWIGTYPE &
|
||||
%{ $input = enumToInteger($input, "$R_class"); %}
|
||||
%typemap(scoercein) enum SWIGTYPE &&
|
||||
%{ $input = enumToInteger($input, "$R_class"); %}
|
||||
%{ $input = enumToInteger($input, "$*R_class"); %}
|
||||
%typemap(scoercein) enum SWIGTYPE *
|
||||
%{ $input = enumToInteger($input, "$R_class"); %}
|
||||
%typemap(scoercein) enum SWIGTYPE *const
|
||||
|
|
@ -138,7 +137,7 @@ string &, std::string &
|
|||
%{ $result = enumFromInteger($result, "$R_class"); %}
|
||||
|
||||
%typemap(scoerceout) enum SWIGTYPE &
|
||||
%{ $result = enumFromInteger($result, "$R_class"); %}
|
||||
%{ $result = enumFromInteger($result, "$*R_class"); %}
|
||||
|
||||
%typemap(scoerceout) enum SWIGTYPE &&
|
||||
%{ $result = enumFromInteger($result, "$R_class"); %}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ function(name, .values, where = topenv(parent.frame()), suffix = "Value")
|
|||
{
|
||||
# Mirror the class definitions via the E analogous to .__C__
|
||||
defName = paste(".__E__", name, sep = "")
|
||||
assign(defName, .values, envir = where)
|
||||
delayedAssign(defName, .values, assign.env = where)
|
||||
|
||||
if(nchar(suffix))
|
||||
name = paste(name, suffix, sep = "")
|
||||
|
|
|
|||
|
|
@ -65,77 +65,38 @@ static String * getRTypeName(SwigType *t, int *outCount = NULL) {
|
|||
*/
|
||||
}
|
||||
|
||||
/*********************
|
||||
Tries to get the name of the R class corresponding to the given type
|
||||
e.g. struct A * is ARef, struct A** is ARefRef.
|
||||
Now handles arrays, i.e. struct A[2]
|
||||
****************/
|
||||
/* --------------------------------------------------------------
|
||||
* Tries to get the resolved name, with options of adding
|
||||
* or removing a layer of references. Take care not
|
||||
* to request both
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
static String *getRClassName(String *retType, int /*addRef*/ = 1, int upRef=0) {
|
||||
String *tmp = NewString("");
|
||||
static String *getRClassName(String *retType, int deRef=0, int upRef=0) {
|
||||
SwigType *resolved = SwigType_typedef_resolve_all(retType);
|
||||
char *retName = Char(SwigType_manglestr(resolved));
|
||||
int ispointer = SwigType_ispointer(resolved);
|
||||
int isreference = SwigType_isreference(resolved);
|
||||
if (upRef) {
|
||||
Printf(tmp, "_p%s", retName);
|
||||
} else{
|
||||
Insert(tmp, 0, retName);
|
||||
SwigType_add_pointer(resolved);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
/*
|
||||
#if 1
|
||||
List *l = SwigType_split(retType);
|
||||
int n = Len(l);
|
||||
if(!l || n == 0) {
|
||||
#ifdef R_SWIG_VERBOSE
|
||||
if (debugMode)
|
||||
Printf(stdout, "SwigType_split return an empty list for %s\n",
|
||||
retType);
|
||||
#endif
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
String *el = Getitem(l, n-1);
|
||||
char *ptr = Char(el);
|
||||
if(strncmp(ptr, "struct ", 7) == 0)
|
||||
ptr += 7;
|
||||
|
||||
Printf(tmp, "%s", ptr);
|
||||
|
||||
if(addRef) {
|
||||
for(int i = 0; i < n; i++) {
|
||||
if(Strcmp(Getitem(l, i), "p.") == 0 ||
|
||||
Strncmp(Getitem(l, i), "a(", 2) == 0)
|
||||
Printf(tmp, "Ref");
|
||||
if (deRef) {
|
||||
if (ispointer) {
|
||||
SwigType_del_pointer(resolved);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
char *retName = Char(SwigType_manglestr(retType));
|
||||
if(!retName)
|
||||
return(tmp);
|
||||
|
||||
if(addRef) {
|
||||
while(retName && strlen(retName) > 1 && strncmp(retName, "_p", 2) == 0) {
|
||||
retName += 2;
|
||||
Printf(tmp, "Ref");
|
||||
if (isreference) {
|
||||
SwigType_del_reference(resolved);
|
||||
}
|
||||
}
|
||||
if(retName[0] == '_')
|
||||
retName ++;
|
||||
Insert(tmp, 0, retName);
|
||||
#endif
|
||||
|
||||
return tmp;
|
||||
*/
|
||||
}
|
||||
String *tmp = NewString("");
|
||||
Insert(tmp, 0, Char(SwigType_manglestr(resolved)));
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
/*********************
|
||||
Tries to get the name of the R class corresponding to the given type
|
||||
e.g. struct A * is ARef, struct A** is ARefRef.
|
||||
Now handles arrays, i.e. struct A[2]
|
||||
****************/
|
||||
/* --------------------------------------------------------------
|
||||
* Tries to get the name of the R class corresponding to the given type
|
||||
* e.g. struct A * is ARef, struct A** is ARefRef.
|
||||
* Now handles arrays, i.e. struct A[2]
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
|
||||
static String * getRClassNameCopyStruct(String *retType, int addRef) {
|
||||
String *tmp = NewString("");
|
||||
|
|
@ -188,12 +149,13 @@ static String * getRClassNameCopyStruct(String *retType, int addRef) {
|
|||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
Write the elements of a list to the File*, one element per line.
|
||||
If quote is true, surround the element with "element".
|
||||
This takes care of inserting a tab in front of each line and also
|
||||
a comma after each element, except the last one.
|
||||
**********************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Write the elements of a list to the File*, one element per line.
|
||||
* If quote is true, surround the element with "element".
|
||||
* This takes care of inserting a tab in front of each line and also
|
||||
* a comma after each element, except the last one.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
|
||||
static void writeListByLine(List *l, File *out, bool quote = 0) {
|
||||
int i, n = Len(l);
|
||||
|
|
@ -222,9 +184,10 @@ R Options (available with -r)\n\
|
|||
|
||||
|
||||
|
||||
/************
|
||||
Display the help for this module on the screen/console.
|
||||
*************/
|
||||
/* -------------------------------------------------------------
|
||||
* Display the help for this module on the screen/console.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
static void showUsage() {
|
||||
fputs(usage, stdout);
|
||||
}
|
||||
|
|
@ -238,10 +201,11 @@ static bool expandTypedef(SwigType *t) {
|
|||
}
|
||||
|
||||
|
||||
/*****
|
||||
Determine whether we should add a .copy argument to the S function
|
||||
that wraps/interfaces to the routine that returns the given type.
|
||||
*****/
|
||||
/* -------------------------------------------------------------
|
||||
* Determine whether we should add a .copy argument to the S function
|
||||
* that wraps/interfaces to the routine that returns the given type.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
static int addCopyParameter(SwigType *type) {
|
||||
int ok = 0;
|
||||
ok = Strncmp(type, "struct ", 7) == 0 || Strncmp(type, "p.struct ", 9) == 0;
|
||||
|
|
@ -253,27 +217,15 @@ static int addCopyParameter(SwigType *type) {
|
|||
}
|
||||
|
||||
static void replaceRClass(String *tm, SwigType *type) {
|
||||
String *tmp = getRClassName(type);
|
||||
String *tmp_base = getRClassName(type, 0);
|
||||
String *tmp_ref = getRClassName(type, 1, 1);
|
||||
String *tmp = getRClassName(type, 0, 0);
|
||||
String *tmp_base = getRClassName(type, 1, 0);
|
||||
String *tmp_ref = getRClassName(type, 0, 1);
|
||||
Replaceall(tm, "$R_class", tmp);
|
||||
Replaceall(tm, "$*R_class", tmp_base);
|
||||
Replaceall(tm, "$&R_class", tmp_ref);
|
||||
Delete(tmp); Delete(tmp_base); Delete(tmp_ref);
|
||||
}
|
||||
|
||||
static bool getNumber(String *value, int* result) {
|
||||
if(Char(value)) {
|
||||
// Check the conversion processed the whole of value by having %c at
|
||||
// the end of the format, and checking that only the first value is
|
||||
// converted. We don't want to convert "3+7" -> 3.
|
||||
char dummy;
|
||||
if (sscanf(Char(value), "%i%c", result, &dummy) == 1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class R : public Language {
|
||||
public:
|
||||
R();
|
||||
|
|
@ -288,7 +240,8 @@ public:
|
|||
|
||||
int classDeclaration(Node *n);
|
||||
int enumDeclaration(Node *n);
|
||||
|
||||
String *enumValue(Node *n);
|
||||
virtual int enumvalueDeclaration(Node *n);
|
||||
int membervariableHandler(Node *n);
|
||||
|
||||
int typedefHandler(Node *n);
|
||||
|
|
@ -392,6 +345,8 @@ protected:
|
|||
|
||||
// Strings into which we cumulate the generated code that is to be written
|
||||
//vto the files.
|
||||
String *enum_values;
|
||||
String *enum_def_calls;
|
||||
String *sfile;
|
||||
String *f_init;
|
||||
String *s_classes;
|
||||
|
|
@ -456,6 +411,8 @@ R::R() :
|
|||
copyStruct(false),
|
||||
memoryProfile(false),
|
||||
aggressiveGc(false),
|
||||
enum_values(0),
|
||||
enum_def_calls(0),
|
||||
sfile(0),
|
||||
f_init(0),
|
||||
s_classes(0),
|
||||
|
|
@ -535,9 +492,10 @@ void R::addSMethodInfo(String *name, String *argType, int nargs) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the name of the new routine.
|
||||
*/
|
||||
/* ----------------------------------------
|
||||
* Returns the name of the new routine.
|
||||
* ------------------------------------------ */
|
||||
|
||||
String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
|
||||
String *funName = SwigType_manglestr(t);
|
||||
|
||||
|
|
@ -574,7 +532,6 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
|
|||
for (i = 0; p; p = nextSibling(p), ++i) {
|
||||
String *arg = Getattr(p, "name");
|
||||
String *lname;
|
||||
|
||||
if (!arg && Cmp(Getattr(p, "type"), "void")) {
|
||||
lname = NewStringf("arg%d", i+1);
|
||||
Setattr(p, "name", lname);
|
||||
|
|
@ -635,6 +592,9 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
|
|||
}
|
||||
Replaceall(tm, "$1", name);
|
||||
Replaceall(tm, "$result", "r_tmp");
|
||||
if (debugMode) {
|
||||
Printf(stdout, "Calling Replace A: %s\n", Getattr(p,"type"));
|
||||
}
|
||||
replaceRClass(tm, Getattr(p,"type"));
|
||||
Replaceall(tm,"$owner", "0");
|
||||
Delete(lstr);
|
||||
|
|
@ -756,6 +716,7 @@ void R::init() {
|
|||
s_classes = NewString("");
|
||||
s_init = NewString("");
|
||||
s_init_routine = NewString("");
|
||||
enum_def_calls = NewString("");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -771,14 +732,19 @@ int R::cDeclaration(Node *n) {
|
|||
#endif
|
||||
|
||||
|
||||
/**
|
||||
Method from Language that is called to start the entire
|
||||
processing off, i.e. the generation of the code.
|
||||
It is called after the input has been read and parsed.
|
||||
Here we open the output streams and generate the code.
|
||||
***/
|
||||
/* -------------------------------------------------------------
|
||||
* Method from Language that is called to start the entire
|
||||
* processing off, i.e. the generation of the code.
|
||||
* It is called after the input has been read and parsed.
|
||||
* Here we open the output streams and generate the code.
|
||||
* ------------------------------------------------------------- */
|
||||
int R::top(Node *n) {
|
||||
String *module = Getattr(n, "name");
|
||||
|
||||
if (debugMode) {
|
||||
Printf(stdout, "<Top> %s\n", module);
|
||||
}
|
||||
|
||||
if(!Rpackage)
|
||||
Rpackage = Copy(module);
|
||||
if(!DllName)
|
||||
|
|
@ -853,9 +819,9 @@ int R::top(Node *n) {
|
|||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
Write the generated code to the .S and the .c files.
|
||||
****************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Write the generated code to the .S and the .c files.
|
||||
* ------------------------------------------------------------- */
|
||||
int R::DumpCode(Node *n) {
|
||||
String *output_filename = NewString("");
|
||||
|
||||
|
|
@ -878,6 +844,7 @@ int R::DumpCode(Node *n) {
|
|||
Printf(scode, "%s\n\n", s_init);
|
||||
Printf(scode, "%s\n\n", s_classes);
|
||||
Printf(scode, "%s\n", sfile);
|
||||
Printf(scode, "%s\n", enum_def_calls);
|
||||
|
||||
Delete(scode);
|
||||
String *outfile = Getattr(n,"outfile");
|
||||
|
|
@ -922,22 +889,23 @@ int R::DumpCode(Node *n) {
|
|||
|
||||
|
||||
|
||||
/*
|
||||
We may need to do more.... so this is left as a
|
||||
stub for the moment.
|
||||
*/
|
||||
/* -------------------------------------------------------------
|
||||
* We may need to do more.... so this is left as a
|
||||
* stub for the moment.
|
||||
* -------------------------------------------------------------*/
|
||||
int R::OutputClassAccessInfo(Hash *tb, File *out) {
|
||||
int n = OutputClassMemberTable(tb, out);
|
||||
OutputClassMethodsTable(out);
|
||||
return n;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Currently this just writes the information collected about the
|
||||
different methods of the C++ classes that have been processed
|
||||
to the console.
|
||||
This will be used later to define S4 generics and methods.
|
||||
**************************************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Currently this just writes the information collected about the
|
||||
* different methods of the C++ classes that have been processed
|
||||
* to the console.
|
||||
* This will be used later to define S4 generics and methods.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::OutputClassMethodsTable(File *) {
|
||||
Hash *tb = ClassMethodsTable;
|
||||
|
||||
|
|
@ -966,20 +934,21 @@ int R::OutputClassMethodsTable(File *) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Iterate over the <class name>_set and <>_get
|
||||
elements and generate the $ and $<- functions
|
||||
that provide constrained access to the member
|
||||
fields in these elements.
|
||||
/* --------------------------------------------------------------
|
||||
* Iterate over the <class name>_set and <>_get
|
||||
* elements and generate the $ and $<- functions
|
||||
* that provide constrained access to the member
|
||||
* fields in these elements.
|
||||
|
||||
tb - a hash table that is built up in functionWrapper
|
||||
as we process each membervalueHandler.
|
||||
The entries are indexed by <class name>_set and
|
||||
<class_name>_get. Each entry is a List *.
|
||||
* tb - a hash table that is built up in functionWrapper
|
||||
* as we process each membervalueHandler.
|
||||
* The entries are indexed by <class name>_set and
|
||||
* <class_name>_get. Each entry is a List *.
|
||||
|
||||
* out - the stram where the code is to be written. This is the S
|
||||
* code stream as we generate only S code here.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
out - the stram where the code is to be written. This is the S
|
||||
code stream as we generate only S code here..
|
||||
*/
|
||||
int R::OutputClassMemberTable(Hash *tb, File *out) {
|
||||
List *keys = Keys(tb), *el;
|
||||
|
||||
|
|
@ -1019,17 +988,18 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
|
|||
return n;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Write the methods for $ or $<- for accessing a member field in an
|
||||
struct or union (or class).
|
||||
className - the name of the struct or union (e.g. Bar for struct Bar)
|
||||
isSet - a logical value indicating whether the method is for
|
||||
modifying ($<-) or accessing ($) the member field.
|
||||
el - a list of length 2 * # accessible member elements + 1.
|
||||
The first element is the name of the class.
|
||||
The other pairs are member name and the name of the R function to access it.
|
||||
out - the stream where we write the code.
|
||||
********************************************************************/
|
||||
/* --------------------------------------------------------------
|
||||
* Write the methods for $ or $<- for accessing a member field in an
|
||||
* struct or union (or class).
|
||||
* className - the name of the struct or union (e.g. Bar for struct Bar)
|
||||
* isSet - a logical value indicating whether the method is for
|
||||
* modifying ($<-) or accessing ($) the member field.
|
||||
* el - a list of length 2 * # accessible member elements + 1.
|
||||
* The first element is the name of the class.
|
||||
* The other pairs are member name and the name of the R function to access it.
|
||||
* out - the stream where we write the code.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::OutputMemberReferenceMethod(String *className, int isSet,
|
||||
List *el, File *out) {
|
||||
int numMems = Len(el), j;
|
||||
|
|
@ -1153,15 +1123,16 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Write the methods for [ or [<- for accessing a member field in an
|
||||
struct or union (or class).
|
||||
className - the name of the struct or union (e.g. Bar for struct Bar)
|
||||
el - a list of length 2 * # accessible member elements + 1.
|
||||
The first element is the name of the class.
|
||||
The other pairs are member name and the name of the R function to access it.
|
||||
out - the stream where we write the code.
|
||||
********************************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Write the methods for [ or [<- for accessing a member field in an
|
||||
* struct or union (or class).
|
||||
* className - the name of the struct or union (e.g. Bar for struct Bar)
|
||||
* el - a list of length 2 * # accessible member elements + 1.
|
||||
* The first element is the name of the class.
|
||||
* The other pairs are member name and the name of the R function to access it.
|
||||
* out - the stream where we write the code.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::OutputArrayMethod(String *className, List *el, File *out) {
|
||||
int numMems = Len(el), j;
|
||||
|
||||
|
|
@ -1192,103 +1163,153 @@ int R::OutputArrayMethod(String *className, List *el, File *out) {
|
|||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
Called when a enumeration is to be processed.
|
||||
We want to call the R function defineEnumeration().
|
||||
tdname is the typedef of the enumeration, i.e. giving its name.
|
||||
*************************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Called when a enumeration is to be processed.
|
||||
* We want to call the R function defineEnumeration().
|
||||
* tdname is the typedef of the enumeration, i.e. giving its name.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::enumDeclaration(Node *n) {
|
||||
if (getCurrentClass() && (cplus_mode != PUBLIC))
|
||||
return SWIG_NOWRAP;
|
||||
if (!ImportMode) {
|
||||
if (getCurrentClass() && (cplus_mode != PUBLIC))
|
||||
return SWIG_NOWRAP;
|
||||
|
||||
String *name = Getattr(n, "name");
|
||||
String *tdname = Getattr(n, "tdname");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
|
||||
/* Using name if tdname is empty. */
|
||||
// TODO - deal with anonymous enumerations
|
||||
// Previous enum code for R didn't wrap them
|
||||
if (!symname || Getattr(n, "unnamedinstance"))
|
||||
return SWIG_NOWRAP;
|
||||
|
||||
if(Len(tdname) == 0)
|
||||
tdname = name;
|
||||
// create mangled name for the enum
|
||||
// This will have content if the %nspace feature is set on
|
||||
// the input file
|
||||
String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
|
||||
String *ename;
|
||||
|
||||
|
||||
if(!tdname || Strcmp(tdname, "") == 0) {
|
||||
String *name = Getattr(n, "name");
|
||||
ename = getRClassName(name);
|
||||
if (debugMode) {
|
||||
Node *current_class = getCurrentClass();
|
||||
String *cl = NewString("");
|
||||
if (current_class) {
|
||||
cl = getEnumClassPrefix();
|
||||
}
|
||||
Printf(stdout, "enumDeclaration: %s, %s, %s, %s, %s\n", name, symname, nspace, ename, cl);
|
||||
}
|
||||
Delete(name);
|
||||
// set up a call to create the R enum structure. The list of
|
||||
// individual elements will be built in enum_code
|
||||
enum_values = 0;
|
||||
// Emit each enum item
|
||||
Language::enumDeclaration(n);
|
||||
return SWIG_OK;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::enumvalueDeclaration(Node *n) {
|
||||
if (getCurrentClass() && (cplus_mode != PUBLIC)) {
|
||||
Printf(stdout, "evd: Not public\n");
|
||||
return SWIG_NOWRAP;
|
||||
}
|
||||
|
||||
String *mangled_tdname = SwigType_manglestr(tdname);
|
||||
String *scode = NewString("");
|
||||
Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *value = Getattr(n, "value");
|
||||
String *name = Getattr(n, "name");
|
||||
Node *parent = parentNode(n);
|
||||
String *parent_name = Getattr(parent, "name");
|
||||
String *newsymname = 0;
|
||||
String *tmpValue;
|
||||
|
||||
Printv(scode, "defineEnumeration('", mangled_tdname, "'",
|
||||
",\n", tab8, tab8, tab4, ".values = c(\n", NIL);
|
||||
|
||||
Node *c;
|
||||
int value = -1; // First number is zero
|
||||
for (c = firstChild(n); c; c = nextSibling(c)) {
|
||||
// const char *tag = Char(nodeType(c));
|
||||
// if (Strcmp(tag,"cdecl") == 0) {
|
||||
name = Getattr(c, "name");
|
||||
String *val = Getattr(c, "enumvalue");
|
||||
if(val && Char(val)) {
|
||||
int inval;
|
||||
if (!getNumber(val, &inval)) {
|
||||
// Conversion failed - use the string value in val.
|
||||
} else {
|
||||
val = NULL;
|
||||
value = inval;
|
||||
}
|
||||
} else {
|
||||
val = NULL;
|
||||
value++;
|
||||
}
|
||||
|
||||
if (val != NULL) {
|
||||
// This won't work in general, but will at least handle cases like (3)
|
||||
// and 3+7, and when it doesn't work, it'll fail noisly rather than
|
||||
// quietly using the wrong enum value like we used to.
|
||||
if (!Strcmp(val, "true")) {
|
||||
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, "TRUE",
|
||||
nextSibling(c) ? ", " : "");
|
||||
} else if (!Strcmp(val, "false")) {
|
||||
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, "FALSE",
|
||||
nextSibling(c) ? ", " : "");
|
||||
} else {
|
||||
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, val,
|
||||
nextSibling(c) ? ", " : "");
|
||||
}
|
||||
} else {
|
||||
Printf(scode, "%s%s%s'%s' = %d%s\n", tab8, tab8, tab8, name, value,
|
||||
nextSibling(c) ? ", " : "");
|
||||
}
|
||||
// }
|
||||
// Strange hack from parent method
|
||||
if (value)
|
||||
tmpValue = NewString(value);
|
||||
else
|
||||
tmpValue = NewString(name);
|
||||
// Note that this is used in enumValue() amongst other places
|
||||
Setattr(n, "value", tmpValue);
|
||||
|
||||
// Deal with enum values that are not int
|
||||
int swigtype = SwigType_type(Getattr(n, "type"));
|
||||
if (swigtype == T_BOOL) {
|
||||
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
|
||||
Setattr(n, "enumvalue", val);
|
||||
} else if (swigtype == T_CHAR) {
|
||||
String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
|
||||
Setattr(n, "enumvalue", val);
|
||||
Delete(val);
|
||||
}
|
||||
|
||||
Printv(scode, "))", NIL);
|
||||
Printf(sfile, "%s\n", scode);
|
||||
if (GetFlag(parent, "scopedenum")) {
|
||||
newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
|
||||
symname = newsymname;
|
||||
}
|
||||
|
||||
Delete(scode);
|
||||
Delete(mangled_tdname);
|
||||
{
|
||||
// Wrap C/C++ enums with constant integers or use the typesafe enum pattern
|
||||
SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
|
||||
if (debugMode) {
|
||||
Printf(stdout, "Setting type: %s\n", Copy(typemap_lookup_type));
|
||||
}
|
||||
Setattr(n, "type", typemap_lookup_type);
|
||||
|
||||
// Simple integer constants
|
||||
// Note these are always generated for anonymous enums, no matter what enum_feature is specified
|
||||
// Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
|
||||
|
||||
String *value = enumValue(n);
|
||||
if (enum_values) {
|
||||
Printf(enum_values, ",\n\"%s\" = %s", name, value);
|
||||
} else {
|
||||
enum_values = NewString("");
|
||||
Printf(enum_values, "\"%s\" = %s", name, value);
|
||||
}
|
||||
|
||||
Delete(value);
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************
|
||||
**************************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Create accessor functions for variables.
|
||||
* Does not create equivalent wrappers for enumerations,
|
||||
* which are handled differently
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::variableWrapper(Node *n) {
|
||||
String *name = Getattr(n, "sym:name");
|
||||
|
||||
if (debugMode) {
|
||||
Printf(stdout, "variableWrapper %s\n", n);
|
||||
}
|
||||
processing_variable = 1;
|
||||
Language::variableWrapper(n); // Force the emission of the _set and _get function wrappers.
|
||||
processing_variable = 0;
|
||||
|
||||
|
||||
SwigType *ty = Getattr(n, "type");
|
||||
String *nodeType = nodeType(n);
|
||||
int addCopyParam = addCopyParameter(ty);
|
||||
|
||||
//XXX
|
||||
processType(ty, n);
|
||||
|
||||
if(!SwigType_isconst(ty)) {
|
||||
if (nodeType && !Strcmp(nodeType, "enumitem")) {
|
||||
/* special wrapper for enums - don't want the R _set, _get functions*/
|
||||
if (debugMode) {
|
||||
Printf(stdout, "variableWrapper enum branch\n");
|
||||
}
|
||||
} else if(!SwigType_isconst(ty)) {
|
||||
Wrapper *f = NewWrapper();
|
||||
Printf(f->def, "%s = \nfunction(value%s)\n{\n",
|
||||
name, addCopyParam ? ", .copy = FALSE" : "");
|
||||
|
|
@ -1306,6 +1327,12 @@ int R::variableWrapper(Node *n) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
* Creates accessor functions for class members.
|
||||
|
||||
* ToDo - this version depends on naming conventions and needs
|
||||
* to be replaced.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
|
||||
int isSet) {
|
||||
|
|
@ -1708,9 +1735,10 @@ void R::dispatchFunction(Node *n) {
|
|||
DelWrapper(f);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
/*--------------------------------------------------------------
|
||||
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
*******************************************************************/
|
||||
int R::functionWrapper(Node *n) {
|
||||
String *fname = Getattr(n, "name");
|
||||
String *iname = Getattr(n, "sym:name");
|
||||
|
|
@ -1752,6 +1780,9 @@ int R::functionWrapper(Node *n) {
|
|||
SwigType *resolved =
|
||||
SwigType_typedef_resolve_all(resultType);
|
||||
if (expandTypedef(resolved)) {
|
||||
if (debugMode) {
|
||||
Printf(stdout, "Setting type: %s\n", resolved);
|
||||
}
|
||||
Setattr(p, "type", Copy(resolved));
|
||||
}
|
||||
}
|
||||
|
|
@ -1764,18 +1795,18 @@ int R::functionWrapper(Node *n) {
|
|||
SwigType_istypedef(type)) {
|
||||
SwigType *resolved =
|
||||
SwigType_typedef_resolve_all(type);
|
||||
if (debugMode)
|
||||
Printf(stdout, "<functionWrapper> resolved %s\n", Copy(unresolved_return_type));
|
||||
if (expandTypedef(resolved)) {
|
||||
type = Copy(resolved);
|
||||
Setattr(n, "type", type);
|
||||
}
|
||||
}
|
||||
if (debugMode)
|
||||
Printf(stdout, "<functionWrapper> unresolved_return_type %s\n",
|
||||
unresolved_return_type);
|
||||
Printf(stdout, "<functionWrapper> unresolved_return_type %s\n", unresolved_return_type);
|
||||
if(processing_member_access_function) {
|
||||
if (debugMode)
|
||||
Printf(stdout, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n",
|
||||
fname, iname, member_name, class_name);
|
||||
Printf(stdout, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n", fname, iname, member_name, class_name);
|
||||
|
||||
if(opaqueClassDeclaration)
|
||||
return SWIG_OK;
|
||||
|
|
@ -2067,14 +2098,12 @@ int R::functionWrapper(Node *n) {
|
|||
/* Deal with the explicit return value. */
|
||||
if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
|
||||
SwigType *retType = Getattr(n, "type");
|
||||
//Printf(stdout, "Return Value for %s, array? %s\n", retType, SwigType_isarray(retType) ? "yes" : "no");
|
||||
/* if(SwigType_isarray(retType)) {
|
||||
defineArrayAccessors(retType);
|
||||
} */
|
||||
|
||||
|
||||
|
||||
Replaceall(tm,"$1", Swig_cresult_name());
|
||||
Replaceall(tm,"$result", "r_ans");
|
||||
if (debugMode){
|
||||
Printf(stdout, "Calling replace D: %s, %s, %s\n", retType, n, tm);
|
||||
}
|
||||
replaceRClass(tm, retType);
|
||||
|
||||
if (GetFlag(n,"feature:new")) {
|
||||
|
|
@ -2161,6 +2190,9 @@ int R::functionWrapper(Node *n) {
|
|||
Delete(smartname);
|
||||
}
|
||||
}
|
||||
if (debugMode) {
|
||||
Printf(stdout, "Calling replace B: %s, %s, %s\n", Getattr(n, "type"), Getattr(n, "sym:name"), getNSpace());
|
||||
}
|
||||
replaceRClass(tm, Getattr(n, "type"));
|
||||
Chop(tm);
|
||||
}
|
||||
|
|
@ -2196,6 +2228,9 @@ int R::functionWrapper(Node *n) {
|
|||
tm = Swig_typemap_lookup("rtype", n, "", 0);
|
||||
if(tm) {
|
||||
SwigType *retType = Getattr(n, "type");
|
||||
if (debugMode) {
|
||||
Printf(stdout, "Calling replace C: %s\n", Copy(retType));
|
||||
}
|
||||
replaceRClass(tm, retType);
|
||||
}
|
||||
|
||||
|
|
@ -2254,15 +2289,16 @@ int R::constantWrapper(Node *n) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
Add the specified routine name to the collection of
|
||||
generated routines that are called from R functions.
|
||||
This is used to register the routines with R for
|
||||
resolving symbols.
|
||||
/*--------------------------------------------------------------
|
||||
* Add the specified routine name to the collection of
|
||||
* generated routines that are called from R functions.
|
||||
* This is used to register the routines with R for
|
||||
* resolving symbols.
|
||||
|
||||
* rname - the name of the routine
|
||||
* nargs - the number of arguments it expects.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
rname - the name of the routine
|
||||
nargs - the number of arguments it expects.
|
||||
******************************************************/
|
||||
int R::addRegistrationRoutine(String *rname, int nargs) {
|
||||
if(!registrationTable)
|
||||
registrationTable = NewHash();
|
||||
|
|
@ -2275,11 +2311,12 @@ int R::addRegistrationRoutine(String *rname, int nargs) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
Write the registration information to an array and
|
||||
create the initialization routine for registering
|
||||
these.
|
||||
******************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Write the registration information to an array and
|
||||
* create the initialization routine for registering
|
||||
* these.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::outputRegistrationRoutines(File *out) {
|
||||
int i, n;
|
||||
if(!registrationTable)
|
||||
|
|
@ -2322,11 +2359,11 @@ int R::outputRegistrationRoutines(File *out) {
|
|||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Process a struct, union or class declaration in the source code,
|
||||
or an anonymous typedef struct
|
||||
/* -------------------------------------------------------------
|
||||
* Process a struct, union or class declaration in the source code,
|
||||
* or an anonymous typedef struct
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
*****************************************************************************/
|
||||
//XXX What do we need to do here -
|
||||
// Define an S4 class to refer to this.
|
||||
|
||||
|
|
@ -2433,9 +2470,7 @@ int R::classDeclaration(Node *n) {
|
|||
class_member_set_functions = NULL;
|
||||
}
|
||||
if (Getattr(n, "has_destructor")) {
|
||||
Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n",
|
||||
getRClassName(Getattr(n, "name")),
|
||||
getRClassName(Getattr(n, "name")));
|
||||
Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name));
|
||||
|
||||
}
|
||||
if(!opaque && !Strcmp(kind, "struct") && copyStruct) {
|
||||
|
|
@ -2509,12 +2544,13 @@ int R::classDeclaration(Node *n) {
|
|||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
Create the C routines that copy an S object of the class given
|
||||
by the given struct definition in Node *n to the C value
|
||||
and also the routine that goes from the C routine to an object
|
||||
of this S class.
|
||||
****************************************************************/
|
||||
/* -------------------------------------------------------------
|
||||
* Create the C routines that copy an S object of the class given
|
||||
* by the given struct definition in Node *n to the C value
|
||||
* and also the routine that goes from the C routine to an object
|
||||
* of this S class.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
/*XXX
|
||||
Clean up the toCRef - make certain the names are correct for the types, etc.
|
||||
in all cases.
|
||||
|
|
@ -2609,13 +2645,14 @@ int R::generateCopyRoutines(Node *n) {
|
|||
|
||||
|
||||
|
||||
/*****
|
||||
Called when there is a typedef to be invoked.
|
||||
/* -------------------------------------------------------------
|
||||
* Called when there is a typedef to be invoked.
|
||||
*
|
||||
* XXX Needs to be enhanced or split to handle the case where we have a
|
||||
* typedef within a classDeclaration emission because the struct/union/etc.
|
||||
* is anonymous.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
XXX Needs to be enhanced or split to handle the case where we have a
|
||||
typedef within a classDeclaration emission because the struct/union/etc.
|
||||
is anonymous.
|
||||
******/
|
||||
int R::typedefHandler(Node *n) {
|
||||
SwigType *tp = Getattr(n, "type");
|
||||
String *type = Getattr(n, "type");
|
||||
|
|
@ -2639,12 +2676,13 @@ int R::typedefHandler(Node *n) {
|
|||
|
||||
|
||||
|
||||
/*********************
|
||||
Called when processing a field in a "class", i.e. struct, union or
|
||||
actual class. We set a state variable so that we can correctly
|
||||
interpret the resulting functionWrapper() call and understand that
|
||||
it is for a field element.
|
||||
**********************/
|
||||
/* --------------------------------------------------------------
|
||||
* Called when processing a field in a "class", i.e. struct, union or
|
||||
* actual class. We set a state variable so that we can correctly
|
||||
* interpret the resulting functionWrapper() call and understand that
|
||||
* it is for a field element.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
int R::membervariableHandler(Node *n) {
|
||||
SwigType *t = Getattr(n, "type");
|
||||
processType(t, n, NULL);
|
||||
|
|
@ -2679,12 +2717,14 @@ String * R::runtimeCode() {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Called when SWIG wants to initialize this
|
||||
We initialize anythin we want here.
|
||||
Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
|
||||
Use Swig_mark_arg() to tell SWIG that it is understood and not to throw an error.
|
||||
**/
|
||||
/* -----------------------------------------------------------------------
|
||||
* Called when SWIG wants to initialize this
|
||||
* We initialize anythin we want here.
|
||||
* Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
|
||||
* Use Swig_mark_arg() to tell SWIG that it is understood and not to
|
||||
* throw an error.
|
||||
* --------------------------------------------------------------*/
|
||||
|
||||
void R::main(int argc, char *argv[]) {
|
||||
init();
|
||||
Preprocessor_define("SWIGR 1", 0);
|
||||
|
|
@ -2767,10 +2807,10 @@ void R::main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Could make this work for String or File and then just store the resulting string
|
||||
rather than the collection of arguments and argc.
|
||||
*/
|
||||
/* -----------------------------------------------------------------------
|
||||
* Could make this work for String or File and then just store the resulting string
|
||||
* rather than the collection of arguments and argc.
|
||||
* ----------------------------------------------------------------------- */
|
||||
int R::outputCommandLineArguments(File *out)
|
||||
{
|
||||
if(Argc < 1 || !Argv || !Argv[0])
|
||||
|
|
@ -2796,18 +2836,17 @@ Language *swig_r(void) {
|
|||
|
||||
|
||||
|
||||
/*************************************************************************************/
|
||||
|
||||
/*
|
||||
Needs to be reworked.
|
||||
*/
|
||||
/* -----------------------------------------------------------------------
|
||||
* Needs to be reworked.
|
||||
*----------------------------------------------------------------------- */
|
||||
String * R::processType(SwigType *t, Node *n, int *nargs) {
|
||||
//XXX Need to handle typedefs, e.g.
|
||||
// a type which is a typedef to a function pointer.
|
||||
|
||||
SwigType *tmp = Getattr(n, "tdname");
|
||||
if (debugMode)
|
||||
Printf(stdout, "processType %s (tdname = %s)\n", Getattr(n, "name"), tmp);
|
||||
Printf(stdout, "processType %s (tdname = %s)(SwigType = %s)\n", Getattr(n, "name"), tmp, Copy(t));
|
||||
|
||||
SwigType *td = t;
|
||||
if (expandTypedef(t) &&
|
||||
|
|
@ -2852,4 +2891,55 @@ String * R::processType(SwigType *t, Node *n, int *nargs) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************************/
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* enumValue()
|
||||
* This method will return a string with an enum value to use in from R when
|
||||
* setting up an enum variable
|
||||
* ------------------------------------------------------------------------ */
|
||||
|
||||
String *R::enumValue(Node *n) {
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *value = Getattr(n, "value");
|
||||
String *newsymname = 0;
|
||||
|
||||
Node *parent = parentNode(n);
|
||||
symname = Getattr(n, "sym:name");
|
||||
|
||||
// parent enumtype has namespace mangled in
|
||||
String *etype = Getattr(parent, "enumtype");
|
||||
// we have to directly call the c wrapper function, as the
|
||||
// R wrapper to the enum is designed to be used after the enum
|
||||
// structures have been created on the R side. This means
|
||||
// that we'll need to construct a .Call expression
|
||||
|
||||
// change the type for variableWrapper
|
||||
if (debugMode) {
|
||||
Printf(stdout, "<enumValue> type set: %s\n", etype);
|
||||
}
|
||||
|
||||
Setattr(n, "type", etype);
|
||||
|
||||
if (!getCurrentClass()) {
|
||||
newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname);
|
||||
// Strange hack to change the name
|
||||
Setattr(n, "name", Getattr(n, "value"));
|
||||
Setattr(n, "sym:name", newsymname);
|
||||
variableWrapper(n);
|
||||
value = Swig_name_get(NSPACE_TODO, newsymname);
|
||||
} else {
|
||||
String *enumClassPrefix = getEnumClassPrefix();
|
||||
newsymname = Swig_name_member(0, enumClassPrefix, symname);
|
||||
Setattr(n, "name", Getattr(n, "value"));
|
||||
Setattr(n, "sym:name", newsymname);
|
||||
variableWrapper(n);
|
||||
value = Swig_name_get(NSPACE_TODO, newsymname);
|
||||
}
|
||||
value = Swig_name_wrapper(value);
|
||||
Replace(value, "_wrap", "R_swig", DOH_REPLACE_FIRST);
|
||||
|
||||
String *valuecall=NewString("");
|
||||
Printv(valuecall, ".Call('", value, "',FALSE, PACKAGE='", Rpackage, "')", NIL);
|
||||
Delete(value);
|
||||
return valuecall;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue