11 if (!fs::exists(path)) {
12 driver_.WLOG(
"import path '{}' does not exist", path.string());
13 return {
nullptr,
false};
16 const fs::path* imported_path =
nullptr;
18 for (
const auto& parsed_path : parsed_paths_) {
19 if (fs::equivalent(parsed_path, path)) {
20 imported_path = &parsed_path;
27 parsed_paths_.emplace_back(std::move(path));
28 imported_path = &parsed_paths_.back();
31 bool seen_entry =
false;
32 for (
const auto& entry : entries_) {
33 if (entry.sym == sym && entry.tag == tag && fs::equivalent(entry.path, *imported_path)) {
39 if (!seen_entry) entries_.emplace_back(
Entry{*imported_path, sym, tag});
40 return {imported_path, fresh};
48 search_paths_.emplace_front(fs::path{});
51 if (
auto env_path = std::getenv(
"MIM_PLUGIN_PATH")) {
52 std::stringstream env_path_stream{env_path};
54 while (std::getline(env_path_stream, sub_path,
':'))
68 insert_ = ++search_paths_.begin();
72 ILOG(
"💾 loading plugin: '{}'", name);
75 WLOG(
"mim/plugin '{}' already loaded", name);
80 if (
auto path = fs::path{name.view()}; path.is_absolute() && fs::is_regular_file(path))
81 handle.reset(
dl::open(name.c_str()));
85 std::error_code ignore;
86 if (
bool reg_file = fs::is_regular_file(full_path, ignore); reg_file && !ignore) {
87 auto path_str = full_path.string();
88 if (handle.reset(
dl::open(path_str.c_str())); handle)
break;
94 if (!handle)
error(
"cannot open plugin '{}'", name);
96 if (
auto get_info =
reinterpret_cast<decltype(&
mim_get_plugin)
>(
dl::get(handle.get(),
"mim_get_plugin"))) {
98 auto info = get_info();
100 if (
auto reg = info.register_normalizers) reg(normalizers_);
101 if (
auto reg = info.register_stages) reg(stages_);
102 if (
auto reg = info.register_backends) reg(backends_);
105 error(
"mim/plugin has no 'mim_get_plugin()'");
110 if (
auto handle =
lookup(plugins_, plugin))
return dl::get(handle->get(), name);
std::pair< const fs::path *, bool > add(fs::path, Sym, ast::Tok::Tag)
Remembers an import or plugin directive and reports whether the resolved file is new.
void add_search_path(fs::path path)
bool is_loaded(Sym sym) const
void * get_fun_ptr(Sym plugin, const char *name)
const auto & search_paths() const
#define MIM_INSTALL_PREFIX
void * get(void *handle, const char *symbol_name)
void * open(const char *filename)
static constexpr auto extension
std::optional< fs::path > path_to_curr_exe()
Yields std::nullopt if an error occurred.
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
auto lookup(const C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
std::string fmt(const char *s, Args &&... args)
Wraps mim::print to output a formatted std:string.
void error(Loc loc, const char *f, Args &&... args)
mim::Plugin mim_get_plugin()
std::unique_ptr< void, void(*)(void *)> Handle