| 188 | } |
| 189 | |
| 190 | Library::Error Library::load(const char exename[], const char path[], bool debug) |
| 191 | { |
| 192 | if (std::strchr(path,',') != nullptr) { |
| 193 | throw std::runtime_error("handling of multiple libraries not supported"); |
| 194 | } |
| 195 | |
| 196 | const bool is_abs_path = Path::isAbsolute(path); |
| 197 | const bool is_rel_path = Path::isRelative(path); |
| 198 | |
| 199 | std::string fullfilename(path); |
| 200 | |
| 201 | // TODO: what if the extension is not .cfg? |
| 202 | // only append extension when we provide the library name and not a path |
| 203 | if (!is_abs_path && !is_rel_path && Path::getFilenameExtension(fullfilename).empty()) |
| 204 | fullfilename += ".cfg"; |
| 205 | |
| 206 | std::string absolute_path; |
| 207 | // open file.. |
| 208 | tinyxml2::XMLDocument doc; |
| 209 | if (debug) |
| 210 | std::cout << "looking for library '" + fullfilename + "'" << std::endl; |
| 211 | tinyxml2::XMLError error = xml_LoadFile(doc, fullfilename.c_str()); |
| 212 | if (error == tinyxml2::XML_ERROR_FILE_NOT_FOUND) { |
| 213 | // only perform further lookups when the given path was not absolute |
| 214 | if (!is_abs_path) |
| 215 | { |
| 216 | std::list<std::string> cfgfolders; |
| 217 | #ifdef FILESDIR |
| 218 | cfgfolders.emplace_back(FILESDIR "/cfg"); |
| 219 | #endif |
| 220 | if (exename) { |
| 221 | std::string exepath(Path::fromNativeSeparators(Path::getPathFromFilename(Path::getCurrentExecutablePath(exename)))); |
| 222 | cfgfolders.push_back(exepath + "cfg"); |
| 223 | cfgfolders.push_back(std::move(exepath)); |
| 224 | } |
| 225 | |
| 226 | while (error == tinyxml2::XML_ERROR_FILE_NOT_FOUND && !cfgfolders.empty()) { |
| 227 | const std::string cfgfolder(cfgfolders.back()); |
| 228 | cfgfolders.pop_back(); |
| 229 | const char *sep = (!cfgfolder.empty() && endsWith(cfgfolder,'/') ? "" : "/"); |
| 230 | const std::string filename(cfgfolder + sep + fullfilename); |
| 231 | if (debug) |
| 232 | std::cout << "looking for library '" + std::string(filename) + "'" << std::endl; |
| 233 | error = xml_LoadFile(doc, filename.c_str()); |
| 234 | if (error != tinyxml2::XML_ERROR_FILE_NOT_FOUND) |
| 235 | absolute_path = Path::getAbsoluteFilePath(filename); |
| 236 | } |
| 237 | } |
| 238 | } else |
| 239 | absolute_path = Path::getAbsoluteFilePath(fullfilename); |
| 240 | |
| 241 | if (error == tinyxml2::XML_SUCCESS) { |
| 242 | if (mData->mFiles.find(absolute_path) == mData->mFiles.end()) { |
| 243 | Error err = load(doc); |
| 244 | if (err.errorcode == ErrorCode::OK) |
| 245 | mData->mFiles.insert(std::move(absolute_path)); |
| 246 | return err; |
| 247 | } |
no test coverage detected