blob: f18dfb11e4583eb791a6c55f3e0450d1cce867a6 [file] [log] [blame]
# File src/library/base/R/dynload.R
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2018 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License is available at
# https://www.R-project.org/Licenses/
dyn.load <-
if(.Platform$OS.type == "windows") {
function(x, local = TRUE, now = TRUE, ...) {
inDL <- function(x, local, now, ..., DLLpath = "")
.Internal(dyn.load(x, local, now, DLLpath))
inDL(x, as.logical(local), as.logical(now), ...)
}
} else {
function(x, local = TRUE, now = TRUE, ...)
.Internal(dyn.load(x, as.logical(local), as.logical(now), ""))
}
dyn.unload <- function(x)
.Internal(dyn.unload(x))
is.loaded <- function(symbol, PACKAGE = "", type = "")
.Internal(is.loaded(symbol, PACKAGE, type))
getNativeSymbolInfo <- function(name, PACKAGE, unlist = TRUE,
withRegistrationInfo = FALSE)
{
if(missing(PACKAGE)) PACKAGE <- ""
if(is.character(PACKAGE))
pkgName <- PACKAGE
else if(inherits(PACKAGE, "DLLInfo")) {
pkgName <- PACKAGE[["path"]]
PACKAGE <- PACKAGE[["info"]]
} else if(inherits(PACKAGE, "DLLInfoReference")) {
pkgName <- character()
} else
stop(gettextf("must pass a package name, %s or %s object",
dQuote("DLLInfo"),
dQuote("DllInfoReference")),
domain = NA)
syms <- lapply(name, function(id) {
v <- .Internal(getSymbolInfo(as.character(id), PACKAGE,
as.logical(withRegistrationInfo)))
if(is.null(v)) {
msg <- paste("no such symbol", id)
if(length(pkgName) && nzchar(pkgName))
msg <- paste(msg, "in package", pkgName)
stop(msg, domain = NA)
}
names(v) <- c("name", "address", "dll", "numParameters")[seq_along(v)]
v
})
if(length(name) == 1L && unlist)
syms <- syms[[1L]]
else
names(syms) <- name
syms
}
getLoadedDLLs <- function() .Internal(getLoadedDLLs())
getDLLRegisteredRoutines <- function(dll, addNames = TRUE)
UseMethod("getDLLRegisteredRoutines")
getDLLRegisteredRoutines.character <- function(dll, addNames = TRUE)
{
dlls <- getLoadedDLLs()
w <- vapply(dlls, function(x) x[["name"]] == dll || x[["path"]] == dll, NA)
if(!any(w))
stop(gettextf("No DLL currently loaded with name or path %s", sQuote(dll)),
domain = NA)
dll <- which.max(w)
if(sum(w) > 1L)
warning(gettextf("multiple DLLs match '%s'. Using '%s'",
names(dll), dlls[[dll]][["path"]]),
domain = NA)
getDLLRegisteredRoutines(dlls[[dll]], addNames)
}
getDLLRegisteredRoutines.DLLInfo <- function(dll, addNames = TRUE)
{
## Provide methods for the different types.
if(!inherits(dll, "DLLInfo"))
stop(gettextf("must specify DLL via a %s object. See getLoadedDLLs()",
dQuote("DLLInfo")),
domain = NA)
info <- dll[["info"]]
els <- .Internal(getRegisteredRoutines(info))
## Put names on the elements by getting the names from each element.
if(addNames) {
els <- lapply(els, function(x) {
if(length(x))
names(x) <- vapply(x, function(z) z$name, "")
x
})
}
class(els) <- "DLLRegisteredRoutines"
els
}
print.NativeRoutineList <-
function(x, ...)
{
if(length(x)) {
m <- data.frame(numParameters =
sapply(x, function(x) x$numParameters),
row.names =
sapply(x, function(x) x$name))
print(m, ...)
}
invisible(x)
}
### This is arranged as a ragged data frame. It may be confusing
### if one reads it row-wise as the columns are related in pairs
### but not across pairs. We might leave it as a list of lists
### but that spans a great deal of vertical space and involves
### a lot of scrolling for the user.
print.DLLRegisteredRoutines <-
function(x, ...)
{
## Create a data frame with as many rows as the maximum number
## of routines in any category. Then fill the column with ""
## and then the actual entries.
n <- lengths(x)
x <- x[n > 0]
n <- max(n)
d <- list()
sapply(names(x),
function(id) {
d[[id]] <<- rep.int("", n)
names <- vapply(x[[id]], function(x) x$name, "")
if(length(names)) d[[id]][seq_along(names)] <<- names
d[[paste(id, "numParameters")]] <<- rep.int("", n)
names <- sapply(x[[id]], function(x) x$numParameters)
if(length(names))
d[[paste(id, "numParameters")]][seq_along(names)] <<- names
})
print(as.data.frame(d), ...)
invisible(x)
}
getCallingDLLe <- function(e)
{
if (is.null(env <- e$".__NAMESPACE__.")) env <- baseenv()
if(!is.null(Ds <- get0("DLLs", envir = env)) && length(Ds))
Ds[[1L]] ## else NULL
}
getCallingDLL <-
function(f = sys.function(-1), doStop = FALSE)
{
e <- environment(f)
if(!isNamespace(e)) {
if(doStop)
stop("function is not in a namespace, so cannot locate associated DLL")
else
return(NULL)
}
if(is.null(r <- getCallingDLLe(e)) && doStop)
stop("looking for DLL for native routine call, but no DLLs in namespace of call")
## else
r
}
print.DLLInfo <- function(x, ...)
{
tmp <- as.data.frame.list(x[c("name", "path", "dynamicLookup")])
names(tmp) <- c("DLL name", "Filename", "Dynamic lookup")
write.dcf(tmp, ...)
invisible(x)
}
print.DLLInfoList <- function(x, ...)
{
if(length(x)) {
m <- data.frame(Filename = sapply(x, function(x) x[["path"]]),
"Dynamic Lookup" =
sapply(x, function(x) x[["dynamicLookup"]]))
print(m, ...)
}
invisible(x)
}
`[.DLLInfoList` <- function(x, ...) structure(NextMethod("["), class = class(x))
`$.DLLInfo` <- function(x, name)
getNativeSymbolInfo(as.character(name), PACKAGE = x)