Context::Context(void) { using FileSystem::Path; // Get the base directory of the application. dir_app = Path(Path::applicationFile()).dirname(); dir_lib = dir_app / ".." / Path("lib"); dir_cfg = dir_app / ".." / Path("etc"); dir_usr_cfg = dir_app / ".." / Path("user") / Path("etc"); dir_www = dir_app / ".." / Path("www"); dir_i18n = dir_app / ".." / Path("i18n"); dir_db = dir_app / ".." / Path("db"); dir_log = dir_app / ".." / Path("log"); dir_scripts = dir_app / ".." / Path("scripts"); #if defined(DUNE_OS_WINDOWS) std::string appdata; System::Environment::get("APPDATA", appdata); Path base = Path(appdata) / DUNE_SHORT_NAME; dir_db = base / "db"; dir_log = base / "log"; #endif // Check if we are running from the development build. if (!dir_cfg.isDirectory() || !dir_www.isDirectory() || !dir_lib.isDirectory()) { dir_lib = dir_app; dir_cfg = Path(DUNE_PATH_SRC) / Path("etc"); dir_usr_cfg = Path(DUNE_PATH_SRC) / Path("user") / Path("etc"); dir_www = Path(DUNE_PATH_SRC) / Path("www"); dir_i18n = Path(DUNE_PATH_BUILD) / Path("DUNEGeneratedFiles") / Path("i18n"); dir_log = dir_app / Path("log"); dir_db = dir_app / Path("db"); dir_scripts = Path(DUNE_PATH_SRC) / Path("programs") / Path("scripts"); } // Initialize UID (this should do...). uid = Time::Clock::getNsec(); }
void Config::parseFile(const char* fname) { Concurrency::ScopedRWLock(m_data_lock, false); char line[c_max_bfr_size] = {0}; char section[c_max_bfr_size] = {0}; char option[c_max_bfr_size] = {0}; char arg[c_max_bfr_size] = {0}; char tmp[c_max_bfr_size] = {0}; char isec[c_max_bfr_size] = {0}; char iopt[c_max_bfr_size] = {0}; size_t line_count = 0; size_t section_count = 0; std::FILE* fd = std::fopen(fname, "r"); if (fd == 0) throw FileOpenError(fname, System::Error::getLastMessage()); while (std::fscanf(fd, " %1023[^\n] ", line) == 1) { ++line_count; // Ignore comments. if (line[0] == ';' || line[0] == '#') continue; // Section name. if (std::sscanf(line, "[%[^]]] ", section) == 1) { String::rtrim(section); if (std::strncmp(section, "Include ", 8) == 0) { Path path = Path(fname).dirname() / String::trim(section + 8); try { parseFile(path.c_str()); } catch (FileOpenError& e) { DUNE_WRN("Config", e.what()); } } else if (std::strncmp(section, "Require ", 8) == 0) { Path path = Path(fname).dirname() / String::trim(section + 8); parseFile(path.c_str()); } ++section_count; } // Option and value. else if (getOptionAndValue(line, option, arg)) { if (section_count == 0) throw SyntaxError(fname, line_count); String::rtrim(option); String::rtrim(arg); bool append = false; if (String::endsWith(String::str(option), "+")) { String::resize(option, -1); // append if a previous value already exists append = m_data[section].find(option) != m_data[section].end(); } std::strncpy(tmp, option, c_max_bfr_size); if (append) { m_data[section][option] += ", "; m_data[section][option] += arg; } else m_data[section][option] = arg; if (std::strlen(arg) < 4) continue; if (std::sscanf(arg, "$(%[^,], %[^)]", isec, iopt) != 2) continue; Sections::iterator sitr = m_data.find(isec); if (sitr == m_data.end()) throw InvalidReference(arg); std::map<std::string, std::string>::iterator oitr = sitr->second.find(iopt); if (oitr == sitr->second.end()) throw InvalidReference(arg); m_data[section][option] = m_data[isec][iopt]; } // Multiline argument. else if (std::sscanf(line, " %[^;|#] ", arg) == 1) { if (section_count == 0) throw SyntaxError(fname, line_count); if (String::endsWith(String::str(option), "+")) String::resize(option, -1); String::rtrim(arg); m_data[section][tmp] += " "; m_data[section][tmp] += arg; } // Syntax error. else { throw SyntaxError(fname, line_count); } } std::fclose(fd); m_files.push_back(fname); }