summaryrefslogtreecommitdiff
path: root/lib/module_loader.cpp
blob: d64722d8c1c966a2d31308205a388277fb636cd4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.

#include <gras/gras.hpp>
#include <boost/filesystem.hpp>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <stdexcept>
#include <iostream>
#include <cstdlib>

namespace fs = boost::filesystem;

#ifdef BOOST_WINDOWS_API
    #include <windows.h>
    static const char *SEP = ";";
    static bool load_module_in_path(const char *path)
    {
        return LoadLibrary(path) != NULL;
    }
#else
    #include <dlfcn.h>
    static const char *SEP = ":";
    static bool load_module_in_path(const char *path)
    {
        return dlopen(path, RTLD_LAZY) != NULL;
    }
#endif

static void load_all_modules_in_path(const fs::path &path)
{
    if (not fs::exists(path)) return;
    if (fs::is_regular_file(path))
    {
        const std::string mod_path = path.string();
        if (not load_module_in_path(mod_path.c_str()))
        {
            std::cerr << "GRAS Module loader fail: " << mod_path << std::endl;
        }
        return;
    }
    if (fs::is_directory(path)) for(
        fs::directory_iterator dir_itr(path);
        dir_itr != fs::directory_iterator();
        ++dir_itr
    ) load_all_modules_in_path(dir_itr->path());
}

static void load_modules_from_paths(const std::string &paths, const fs::path &suffix)
{
    if (paths.empty()) return;
    BOOST_FOREACH(const std::string &path, boost::tokenizer<boost::char_separator<char> > (paths, boost::char_separator<char>(SEP)))
    {
        if (path.empty()) continue;
        load_all_modules_in_path(fs::path(path) / suffix);
    }
}

static std::string my_get_env(const std::string &name, const std::string &defalt)
{
    const char *env_var = std::getenv(name.c_str());
    return (env_var != NULL)? env_var : defalt;
}

GRAS_STATIC_BLOCK(gras_module_loader)
{
    //!search the GRAS_ROOT directory for this install
    load_modules_from_paths(my_get_env("GRAS_ROOT", "@GRAS_ROOT@"), fs::path("") / "lib@LIB_SUFFIX@" / "gras" / "modules");

    //!search the GRAS_PATH search directories for modules
    load_modules_from_paths(my_get_env("GRAS_PATH", ""), fs::path("") / "lib@LIB_SUFFIX@" / "gras" / "modules");

    //!search the explicit module paths
    load_modules_from_paths(my_get_env("GRAS_MODULE_PATH", ""), fs::path(""));
}