/* -*- C++ -*- * Copyright ©2005 Hugo Mills * * This software is distributed under the terms of the GNU GPL * For more information on the GPL, see the file COPYING or * visit http://www.gnu.org/ * * This software is distributed without warranty */ #include "magellan/options.h" #include "config.h" #include #include #include #include #include #include #include Options* opts; const int NO_PLUGIN_PATH = 256; const int NO_DATA_PATH = 257; struct option LONG_OPTS[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "config", required_argument, NULL, 'c' }, { "plugin-path", required_argument, NULL, 'P' }, { "no-plugin-path", no_argument, NULL, NO_PLUGIN_PATH }, { "include", required_argument, NULL, 'I' }, { "no-include-path", no_argument, NULL, NO_DATA_PATH }, { "debug", required_argument, NULL, 'D' } }; const char* SHORT_OPTS = "hvc:P:I:D::"; Options::Options(int argc, char* argv[]) : _debug_plugin(0), _debug_parse(0), _debug_render(0), _debug_lexer(0) { int index; int opt; int i; std::string path; std::string cfilename = ""; std::string homedir_str = ""; char* homedir = getenv("HOME"); if(homedir != NULL) { homedir_str = homedir; if(homedir_str[homedir_str.length()-1] != '/') homedir_str += "/"; } cfilename = homedir_str + ".magellanrc"; add_plugin_path("/usr/lib/magellan/plugins/"); add_plugin_path("/usr/local/lib/magellan/plugins/"); add_plugin_path(homedir_str + "lib/magellan/plugins/"); add_plugin_path("./plugins/"); add_data_path("/usr/lib/magellan/"); add_data_path("/usr/local/lib/magellan/"); add_data_path(homedir_str + "lib/magellan/"); while((opt = getopt_long(argc, argv, SHORT_OPTS, LONG_OPTS, &index)) != -1) { switch(opt) { case 'h': help(); exit(0); break; case 'v': std::cout << "Magellan v" PACKAGE_VERSION " ©2008 HRMills"; std::cout << std::endl; exit(0); break; case 'c': cfilename = optarg; break; case 'D': if(optarg) { i = 0; char c; while((c = optarg[i++]) != 0) { switch(c) { case 'p': _debug_plugin++; break; case 'c': _debug_parse++; break; case 'r': _debug_render++; break; case 'l': _debug_lexer++; break; default: std::cerr << "Debug option " << c << " not known" << std::endl; help(); exit(2); break; } } } else { _debug_plugin = _debug_parse = 1; } break; case NO_PLUGIN_PATH: clear_plugin_path(); break; case 'P': path = optarg; if(optarg[strlen(optarg)-1] != '/') path += "/"; add_plugin_path(path); break; case NO_DATA_PATH: clear_data_path(); break; case 'I': path = optarg; if(optarg[strlen(optarg)-1] != '/') path += "/"; add_data_path(path); break; } } if(cfilename == "-") { if(debug_parse() >= 1) std::cerr << "Opening config from standard input" << std::endl; _configfile = &std::cin; } else { if(debug_parse() >= 1) std::cerr << "Opening config file " << cfilename << std::endl; _configfile = new std::ifstream(cfilename.c_str()); if(!_configfile->good()) { std::cerr << "Unable to open config file " << cfilename << std::endl; exit(1); } } } Options::~Options() { if(_configfile != NULL) delete _configfile; } void Options::help(void) const { std::cerr << "Usage: magellan [options]\n" << "Options:\n" << "\t-h, --help\t\tShow this text\n" << "\t-c, --config=\tUse specified configuration file\n" << "\t-P, --plugin-path=\tAdd to search path for plugins\n" << "\t --no-plugin-path\tStart with empty plugin path\n" << "\t-I, --include=\tAdd to search path for data\n" << "\t --no-include-path\tStart with empty include path\n" << "\t-D, --debug[=key]\tPrint debug info. key is one or more of:\n" << "\t\t\t\t\tp\tPlugin loader\n" << "\t\t\t\t\tc\tConfiguration parser\n" << "\t\t\t\t\tr\tRender engine\n" << "\t\t\t\t\tl\tLexer\n" << std::flush; } bool fileexists(const std::string& name) { struct stat buf; return stat(name.c_str(), &buf) == 0; } std::string Options::find_data_file( const std::string& sub_path, const std::string& filename ) const { if(debug_parse() >= 3) std::cerr << "Looking for data file: " << sub_path << " " << filename << std::endl; if(filename[0] == '/') { // It's an absolute path, so don't search if(fileexists(filename)) return filename; if(debug_parse() >= 3) std::cerr << "Absolute path not found" << std::endl; } else { std::string spath = sub_path; if(spath[spath.length()-1] != '/') spath += "/"; for(std::list::const_iterator it1 = data_search_path.begin(); it1 != data_search_path.end(); it1++) { std::string fullname = *it1 + spath + filename; if(debug_parse() >= 3) std::cerr << "Looking in " << fullname << std::endl; if(fileexists(fullname)) return fullname; } } return ""; }