diff --git a/data/blueprints/library/square-dig.csv b/data/blueprints/library/square-dig.csv index 328710ddb..548c5c3f2 100644 --- a/data/blueprints/library/square-dig.csv +++ b/data/blueprints/library/square-dig.csv @@ -1,4 +1,4 @@ -#dig start(2,2) +#dig start(2;2) This is a library placeholder for use during quickfort development d,d,d d, ,d d,d,d diff --git a/library/Core.cpp b/library/Core.cpp index a9fe9a69a..20d9c994b 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1737,18 +1737,35 @@ bool Core::Init() virtual_identity::Init(this); // copy over default config files if necessary - std::vector config_files; - std::vector default_config_files; - if (Filesystem::listdir("dfhack-config", config_files) != 0) + std::map config_files; + std::map default_config_files; + if (Filesystem::listdir_recursive("dfhack-config", config_files, 10, false) != 0) con.printerr("Failed to list directory: dfhack-config"); - else if (Filesystem::listdir("dfhack-config/default", default_config_files) != 0) + else if (Filesystem::listdir_recursive("dfhack-config/default", default_config_files, 10, false) != 0) con.printerr("Failed to list directory: dfhack-config/default"); else { + // ensure all config file directories exist before we start copying files for (auto it = default_config_files.begin(); it != default_config_files.end(); ++it) { - std::string filename = *it; - if (std::find(config_files.begin(), config_files.end(), filename) == config_files.end()) + // skip over files + if (!it->second) + continue; + std::string dirname = "dfhack-config/" + it->first; + if (!Filesystem::mkdir_recursive(dirname)) + { + con.printerr("Failed to create config directory: '%s'\n", dirname.c_str()); + } + } + + // copy files from the default tree that don't already exist in the config tree + for (auto it = default_config_files.begin(); it != default_config_files.end(); ++it) + { + // skip over directories + if (it->second) + continue; + std::string filename = it->first; + if (config_files.find(filename) == config_files.end()) { std::string src_file = std::string("dfhack-config/default/") + filename; if (!Filesystem::isfile(src_file)) diff --git a/library/include/modules/Filesystem.h b/library/include/modules/Filesystem.h index bc0953d27..3252be007 100644 --- a/library/include/modules/Filesystem.h +++ b/library/include/modules/Filesystem.h @@ -161,6 +161,6 @@ namespace DFHack { DFHACK_EXPORT int64_t mtime (std::string path); DFHACK_EXPORT int listdir (std::string dir, std::vector &files); DFHACK_EXPORT int listdir_recursive (std::string dir, std::map &files, - int depth = 10, std::string prefix = ""); + int depth = 10, bool include_prefix = true); } } diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index ddc091525..c0d0860ad 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -205,34 +205,46 @@ int Filesystem::listdir (std::string dir, std::vector &files) return 0; } -int Filesystem::listdir_recursive (std::string dir, std::map &files, - int depth /* = 10 */, std::string prefix /* = "" */) +// prefix is the top-level dir where we started recursing +// path is the relative path under the prefix; must be empty or end in a '/' +// files is the output list of files and directories (bool == true for dir) +// depth is the remaining dir depth to recurse into. function returns -1 if +// we haven't finished recursing when we run out of depth. +// include_prefix controls whether the directory where we started recursing is +// included in the filenames returned in files. +static int listdir_recursive_impl (std::string prefix, std::string path, + std::map &files, int depth, bool include_prefix) { - int err; if (depth < 0) return -1; - if (prefix == "") - prefix = dir; - std::vector tmp; - err = listdir(dir, tmp); + std::string prefixed_path = prefix + "/" + path; + std::vector curdir_files; + int err = Filesystem::listdir(prefixed_path, curdir_files); if (err) return err; - for (auto file = tmp.begin(); file != tmp.end(); ++file) + for (auto file = curdir_files.begin(); file != curdir_files.end(); ++file) { if (*file == "." || *file == "..") continue; - std::string rel_path = prefix + "/" + *file; - if (isdir(rel_path)) + std::string prefixed_file = prefixed_path + *file; + std::string path_file = path + *file; + if (Filesystem::isdir(prefixed_file)) { - files.insert(std::pair(rel_path, true)); - err = listdir_recursive(dir + "/" + *file, files, depth - 1, rel_path); + files.insert(std::pair(include_prefix ? prefixed_file : path_file, true)); + err = listdir_recursive_impl(prefix, path_file + "/", files, depth - 1, include_prefix); if (err) return err; } else { - files.insert(std::pair(rel_path, false)); + files.insert(std::pair(include_prefix ? prefixed_file : path_file, false)); } } return 0; } + +int Filesystem::listdir_recursive (std::string dir, std::map &files, + int depth /* = 10 */, bool include_prefix /* = true */) +{ + return listdir_recursive_impl(dir, "", files, depth, include_prefix); +}