Statistics
| Branch: | Tag: | Revision:

root / host / lib / load_modules.cpp @ 38995223

History | View | Annotate | Download (4.48 KB)

1
//
2
// Copyright 2010 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#include <uhd/utils/static.hpp>
19
#include <boost/format.hpp>
20
#include <boost/foreach.hpp>
21
#include <boost/algorithm/string.hpp>
22
#include <boost/filesystem.hpp>
23
#include <boost/program_options.hpp>
24
#include <iostream>
25
#include <stdexcept>
26

    
27
namespace po = boost::program_options;
28
namespace fs = boost::filesystem;
29

    
30
/***********************************************************************
31
 * Module Load Function
32
 **********************************************************************/
33
#ifdef HAVE_DLFCN_H
34
#include <dlfcn.h>
35
static const std::string env_path_sep = ":";
36

    
37
static void load_module(const std::string &file_name){
38
    if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){
39
        throw std::runtime_error(str(
40
            boost::format("dlopen failed to load \"%s\"") % file_name
41
        ));
42
    }
43
}
44

    
45
#elif HAVE_WINDOWS_H
46
#include <windows.h>
47
static const std::string env_path_sep = ";";
48

    
49
static void load_module(const std::string &file_name){
50
    if (LoadLibrary(file_name.c_str()) == NULL){
51
        throw std::runtime_error(str(
52
            boost::format("LoadLibrary failed to load \"%s\"") % file_name
53
        ));
54
    }
55
}
56

    
57
#else
58
static const std::string env_path_sep = ":";
59

    
60
static void load_module(const std::string &file_name){
61
    throw std::runtime_error(str(
62
        boost::format("Module loading not supported: Cannot load \"%s\"") % file_name
63
    ));
64
}
65

    
66
#endif
67

    
68
/***********************************************************************
69
 * Load Modules
70
 **********************************************************************/
71
/*!
72
 * Load all modules in a given path.
73
 * This will recurse into sub-directories.
74
 * Does not throw, prints to std error.
75
 * \param path the filesystem path
76
 */
77
static void load_path(const fs::path &path){
78
    if (not fs::exists(path)){
79
        std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl;
80
        return;
81
    }
82

    
83
    //try to load the files in this path
84
    if (fs::is_directory(path)){
85
        for(
86
            fs::directory_iterator dir_itr(path);
87
            dir_itr != fs::directory_iterator();
88
            ++dir_itr
89
        ){
90
            load_path(dir_itr->path());
91
        }
92
        return;
93
    }
94

    
95
    //its not a directory, try to load it
96
    try{
97
        load_module(path.file_string());
98
    }
99
    catch(const std::exception &err){
100
        std::cerr << boost::format("Error: %s") % err.what() << std::endl;
101
    }
102
}
103

    
104
//! The string constant for the module path environment variable
105
static const std::string MODULE_PATH_KEY = "UHD_MODULE_PATH";
106

    
107
/*!
108
 * Name mapper function for the environment variable parser.
109
 * Map environment variable names (that we use) to option names.
110
 * \param the variable name
111
 * \return the option name or blank string
112
 */
113
static std::string name_mapper(const std::string &var_name){
114
    if (var_name == MODULE_PATH_KEY) return var_name;
115
    return "";
116
}
117

    
118
/*!
119
 * Load all the modules given by the module path enviroment variable.
120
 * The path variable may be several paths split by path separators.
121
 */
122
UHD_STATIC_BLOCK(load_modules){
123
    //register the options
124
    std::string env_module_path;
125
    po::options_description desc("UHD Module Options");
126
    desc.add_options()
127
        (MODULE_PATH_KEY.c_str(), po::value<std::string>(&env_module_path)->default_value(""))
128
    ;
129

    
130
    //parse environment variables
131
    po::variables_map vm;
132
    po::store(po::parse_environment(desc, &name_mapper), vm);
133
    po::notify(vm);
134

    
135
    if (env_module_path == "") return;
136
    //std::cout << "env_module_path: " << env_module_path << std::endl;
137

    
138
    //split the path at the path separators
139
    std::vector<std::string> module_paths;
140
    boost::split(module_paths, env_module_path, boost::is_any_of(env_path_sep));
141

    
142
    //load modules in each path
143
    BOOST_FOREACH(const std::string &module_path, module_paths){
144
        load_path(fs::system_complete(fs::path(module_path)));
145
    }
146
}