static std::string getLibraryFunctionName()

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 "";
}