recurs-ify default config copying logic

I refactored Filesystem::listdir_recursive to support removing the path
prefix from the returned files list. There are no current calls that
make use of the prefix parameter, so I converted it into a boolean.
Current usages will use the new default parameter and will not see any
changed behavior.
develop
Myk Taylor 2020-07-18 22:22:37 -07:00
parent 2026c2b0c3
commit 16cfd34678
4 changed files with 50 additions and 21 deletions

@ -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

1 #dig start(2,2) #dig start(2;2) This is a library placeholder for use during quickfort development
2 d,d,d d,d,d
3 d, ,d d, ,d
4 d,d,d d,d,d

@ -1737,18 +1737,35 @@ bool Core::Init()
virtual_identity::Init(this);
// copy over default config files if necessary
std::vector<std::string> config_files;
std::vector<std::string> default_config_files;
if (Filesystem::listdir("dfhack-config", config_files) != 0)
std::map<std::string, bool> config_files;
std::map<std::string, bool> 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))

@ -161,6 +161,6 @@ namespace DFHack {
DFHACK_EXPORT int64_t mtime (std::string path);
DFHACK_EXPORT int listdir (std::string dir, std::vector<std::string> &files);
DFHACK_EXPORT int listdir_recursive (std::string dir, std::map<std::string, bool> &files,
int depth = 10, std::string prefix = "");
int depth = 10, bool include_prefix = true);
}
}

@ -205,34 +205,46 @@ int Filesystem::listdir (std::string dir, std::vector<std::string> &files)
return 0;
}
int Filesystem::listdir_recursive (std::string dir, std::map<std::string, bool> &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<std::string, bool> &files, int depth, bool include_prefix)
{
int err;
if (depth < 0)
return -1;
if (prefix == "")
prefix = dir;
std::vector<std::string> tmp;
err = listdir(dir, tmp);
std::string prefixed_path = prefix + "/" + path;
std::vector<std::string> 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<std::string, bool>(rel_path, true));
err = listdir_recursive(dir + "/" + *file, files, depth - 1, rel_path);
files.insert(std::pair<std::string, bool>(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<std::string, bool>(rel_path, false));
files.insert(std::pair<std::string, bool>(include_prefix ? prefixed_file : path_file, false));
}
}
return 0;
}
int Filesystem::listdir_recursive (std::string dir, std::map<std::string, bool> &files,
int depth /* = 10 */, bool include_prefix /* = true */)
{
return listdir_recursive_impl(dir, "", files, depth, include_prefix);
}