Add the ability to specify "load_module" and "use" search paths. The capability is primitive and it is currently used by chaiscript_eval to set a single path from environment variables

This commit is contained in:
Jason Turner 2010-03-18 22:53:52 +00:00
parent 7080f5d681
commit 7ac9ea7249
3 changed files with 94 additions and 25 deletions

View File

@ -113,6 +113,18 @@ namespace chaiscript
virtual ~Eval_Error() throw() {} virtual ~Eval_Error() throw() {}
}; };
/**
* Errors generated when loading a file
*/
struct File_Not_Found_Error : public std::runtime_error {
File_Not_Found_Error(const std::string &filename)
: std::runtime_error("File Not Found: " + filename)
{ }
virtual ~File_Not_Found_Error() throw() {}
};
/** /**
* Special type for returned values * Special type for returned values
*/ */

View File

@ -225,6 +225,9 @@ namespace chaiscript
std::map<std::string, Loadable_Module_Ptr> loaded_modules; std::map<std::string, Loadable_Module_Ptr> loaded_modules;
std::set<std::string> active_loaded_modules; std::set<std::string> active_loaded_modules;
std::vector<std::string> modulepaths;
std::vector<std::string> usepaths;
Eval_Engine engine; Eval_Engine engine;
@ -301,26 +304,55 @@ namespace chaiscript
void use(const std::string &filename) void use(const std::string &filename)
{ {
#ifndef CHAISCRIPT_NO_THREADS for (size_t i = 0; i < usepaths.size(); ++i)
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
boost::shared_lock<boost::shared_mutex> l2(mutex);
#endif
if (loaded_files.count(filename) == 0)
{ {
#ifndef CHAISCRIPT_NO_THREADS
l2.unlock();
#endif
eval_file(filename);
} else {
engine.sync_cache();
}
try {
const std::string appendedpath = usepaths[i] + filename;
#ifndef CHAISCRIPT_NO_THREADS
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
boost::shared_lock<boost::shared_mutex> l2(mutex);
#endif
if (loaded_files.count(appendedpath) == 0)
{
#ifndef CHAISCRIPT_NO_THREADS
l2.unlock();
#endif
eval_file(appendedpath);
} else {
engine.sync_cache();
}
} catch (const File_Not_Found_Error &) {
if (i == usepaths.size() - 1)
{
throw File_Not_Found_Error(filename);
}
// failed to load, try the next path
}
}
} }
public: public:
ChaiScript_System() { ChaiScript_System(const std::vector<std::string> &t_modulepaths = std::vector<std::string>(),
const std::vector<std::string> &t_usepaths = std::vector<std::string>())
: modulepaths(t_modulepaths), usepaths(t_usepaths) {
if (modulepaths.empty())
{
modulepaths.push_back("");
}
if (usepaths.empty())
{
usepaths.push_back("");
}
loaded_files.insert("__EVAL__"); // Make sure the default name is already registered loaded_files.insert("__EVAL__"); // Make sure the default name is already registered
build_eval_system(); build_eval_system();
} }
@ -408,18 +440,21 @@ namespace chaiscript
postfixes.push_back(".so"); postfixes.push_back(".so");
postfixes.push_back(""); postfixes.push_back("");
for (size_t i = 0; i < prefixes.size(); ++i) for (size_t i = 0; i < modulepaths.size(); ++i)
{ {
for (size_t j = 0; j < postfixes.size(); ++j) for (size_t j = 0; j < prefixes.size(); ++j)
{
for (size_t k = 0; k < postfixes.size(); ++k)
{ {
try { try {
std::string name = prefixes[i] + t_module_name + postfixes[j]; std::string name = modulepaths[i] + prefixes[j] + t_module_name + postfixes[k];
load_module(t_module_name, name); load_module(t_module_name, name);
return; return;
} catch (const load_module_error &) { } catch (const load_module_error &) {
// Try next set // Try next set
} }
} }
}
} }
throw load_module_error("Unable to find module: " + t_module_name); throw load_module_error("Unable to find module: " + t_module_name);
@ -495,7 +530,7 @@ namespace chaiscript
std::ifstream infile (filename.c_str(), std::ios::in | std::ios::ate); std::ifstream infile (filename.c_str(), std::ios::in | std::ios::ate);
if (!infile.is_open()) { if (!infile.is_open()) {
throw std::runtime_error("Can not open: " + filename); throw File_Not_Found_Error(filename);
} }
std::streampos size = infile.tellg(); std::streampos size = infile.tellg();

View File

@ -52,7 +52,29 @@ std::string get_next_command() {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
std::string input; std::string input;
chaiscript::ChaiScript chai;
std::vector<std::string> usepaths;
std::vector<std::string> modulepaths;
const char *usepath = getenv("CHAI_USE_PATH");
const char *modulepath = getenv("CHAI_MODULE_PATH");
usepaths.push_back("");
if (usepath)
{
usepaths.push_back(usepath);
}
modulepaths.push_back("");
if (modulepath)
{
modulepaths.push_back(modulepath);
}
chaiscript::ChaiScript chai(modulepaths,usepaths);
chai.add(chaiscript::fun(&exit), "exit"); chai.add(chaiscript::fun(&exit), "exit");
chai.add(chaiscript::fun(&throws_exception), "throws_exception"); chai.add(chaiscript::fun(&throws_exception), "throws_exception");