in src/debugger/SourceFileManager.cpp [240:280]
static std::string getLibraryFunctionName(SEXP _func) {
ShieldSEXP func = _func;
if (func.type() == BUILTINSXP || func.type() == SPECIALSXP) {
int offset = getPrimOffset(func);
const char *name = getFunTabName(offset);
if (strlen(name) == 0) return "";
return "base::" + quoteIfNeeded(name);
}
if (func.type() != CLOSXP) return "";
ShieldSEXP env = CLOENV(func);
std::string package;
PrSEXP names;
if (env == R_BaseEnv || env == R_BaseNamespace) {
package = "base";
names = RI->ls(R_BaseEnv, named("all.names", true));
} else {
static PrSEXP getExports = RI->evalCode(
"function(env) tryCatch({\n"
" if (!isNamespace(env)) return(NULL)\n"
" exports <- .getNamespaceInfo(env, 'exports')\n"
" if (is.null(exports)) return(NULL)\n"
" return(list(getNamespaceName(env), ls(exports, all.names = TRUE)))\n"
"}, error = function(e) { yay2 <<- env; yay <<- e })", R_BaseEnv);
ShieldSEXP res = getExports(env);
if (res == R_NilValue) return "";
package = asStringUTF8(res[0]);
names = res[1];
}
if (names.type() != STRSXP) return "";
int length = names.length();
for (int i = 0; i < length; ++i) {
SEXP var = env.getVar(stringEltNative(names, i), false);
if (TYPEOF(var) == PROMSXP) var = PRVALUE(var);
if (func == var) {
return quoteIfNeeded(package) + "::" + quoteIfNeeded(stringEltUTF8(names, i));
}
}
return "";
}