| 1839 | } |
| 1840 | |
| 1841 | AnyMap AnyMap::fromYamlFile(const string& name, const string& parent_name) |
| 1842 | { |
| 1843 | string fullName; |
| 1844 | // See if a file with this name exists in a path relative to the parent file |
| 1845 | size_t islash = parent_name.find_last_of("/\\"); |
| 1846 | if (islash != npos) { |
| 1847 | string parent_path = parent_name.substr(0, islash); |
| 1848 | if (std::ifstream(parent_path + "/" + name).good()) { |
| 1849 | fullName = parent_path + "/" + name; |
| 1850 | } |
| 1851 | } |
| 1852 | // Otherwise, search the Cantera include path for the file |
| 1853 | if (fullName.empty()) { |
| 1854 | fullName = findInputFile(name); |
| 1855 | } |
| 1856 | |
| 1857 | // Check for an already-parsed YAML file with the same last-modified time, |
| 1858 | // and return that if possible |
| 1859 | auto mtime = std::filesystem::last_write_time(fullName); |
| 1860 | std::unique_lock<std::mutex> lock(yaml_cache_mutex); |
| 1861 | auto iter = s_cache.find(fullName); |
| 1862 | if (iter != s_cache.end() && iter->second.second == mtime) { |
| 1863 | return iter->second.first; |
| 1864 | } |
| 1865 | |
| 1866 | if (!std::ifstream(fullName).good()) { |
| 1867 | throw CanteraError("AnyMap::fromYamlFile", "Input file '{}' not found " |
| 1868 | "on the Cantera search path.", name); |
| 1869 | } |
| 1870 | |
| 1871 | // Generate an AnyMap from the YAML file and store it in the cache |
| 1872 | auto& [cache_item, cache_time] = s_cache[fullName]; |
| 1873 | cache_time = mtime; |
| 1874 | try { |
| 1875 | YAML::Node node = YAML::LoadFile(fullName); |
| 1876 | cache_item = node.as<AnyMap>(); |
| 1877 | cache_item.setMetadata("filename", AnyValue(fullName)); |
| 1878 | cache_item.applyUnits(); |
| 1879 | } catch (YAML::Exception& err) { |
| 1880 | s_cache.erase(fullName); |
| 1881 | AnyMap fake; |
| 1882 | fake.setLoc(err.mark.line, err.mark.column); |
| 1883 | fake.setMetadata("filename", AnyValue(fullName)); |
| 1884 | throw InputFileError("AnyMap::fromYamlFile", fake, err.msg); |
| 1885 | } catch (CanteraError&) { |
| 1886 | s_cache.erase(fullName); |
| 1887 | throw; |
| 1888 | } |
| 1889 | cache_item["__file__"] = fullName; |
| 1890 | cache_item.setLoc(0, 0); |
| 1891 | |
| 1892 | if (cache_item.hasKey("deprecated")) { |
| 1893 | warn_deprecated(fullName, cache_item["deprecated"].asString()); |
| 1894 | } |
| 1895 | |
| 1896 | // Return a copy of the AnyMap |
| 1897 | return cache_item; |
| 1898 | } |
nothing calls this directly
no test coverage detected