diff options
author | Kurtis Rader <krader@skepticism.us> | 2016-05-02 21:15:43 -0700 |
---|---|---|
committer | Kurtis Rader <krader@skepticism.us> | 2016-05-02 21:23:33 -0700 |
commit | 8d6b88eb5d0ba6b422d2e37873b4d3026d2fbcd0 (patch) | |
tree | 9d7bd49efc9302e957c0f5481d4321e01ac0bf98 /src | |
parent | 80250c0729d382aa60b4c6ff6210b66b470ad40b (diff) |
restyle path module to match project style
Reduces lint errors from 30 to 21 (-30%). Line count from 597 to 481 (-19%).
Another step in resolving issue #2902.
Diffstat (limited to 'src')
-rw-r--r-- | src/path.cpp | 415 | ||||
-rw-r--r-- | src/path.h | 125 |
2 files changed, 212 insertions, 328 deletions
diff --git a/src/path.cpp b/src/path.cpp index ebe14165..d80ffadf 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -1,118 +1,90 @@ -#include <wchar.h> +// Directory utilities. This library contains functions for locating configuration directories, for +// testing if a command with a given name can be found in the PATH, and various other path-related +// issues. +#include <assert.h> +#include <errno.h> #include <sys/stat.h> #include <unistd.h> -#include <errno.h> -#include <assert.h> +#include <wchar.h> #include <string> #include <vector> -#include "fallback.h" // IWYU pragma: keep #include "common.h" #include "env.h" -#include "wutil.h" // IWYU pragma: keep -#include "path.h" #include "expand.h" +#include "fallback.h" // IWYU pragma: keep +#include "path.h" +#include "wutil.h" // IWYU pragma: keep -/** - Unexpected error in path_get_path() -*/ -#define MISSING_COMMAND_ERR_MSG _( L"Error while searching for command '%ls'" ) +/// Unexpected error in path_get_path(). +#define MISSING_COMMAND_ERR_MSG _(L"Error while searching for command '%ls'") -static bool path_get_path_core(const wcstring &cmd, wcstring *out_path, const env_var_t &bin_path_var) -{ +static bool path_get_path_core(const wcstring &cmd, wcstring *out_path, + const env_var_t &bin_path_var) { int err = ENOENT; debug(3, L"path_get_path( '%ls' )", cmd.c_str()); - /* If the command has a slash, it must be a full path */ - if (cmd.find(L'/') != wcstring::npos) - { - if (waccess(cmd, X_OK)==0) - { + // If the command has a slash, it must be a full path. + if (cmd.find(L'/') != wcstring::npos) { + if (waccess(cmd, X_OK) == 0) { struct stat buff; - if (wstat(cmd, &buff)) - { + if (wstat(cmd, &buff)) { return false; } - if (S_ISREG(buff.st_mode)) - { - if (out_path) - out_path->assign(cmd); + if (S_ISREG(buff.st_mode)) { + if (out_path) out_path->assign(cmd); return true; - } - else - { + } else { errno = EACCES; return false; } - } - else - { + } else { return false; } - } - else - { + } else { wcstring bin_path; - if (! bin_path_var.missing()) - { + if (!bin_path_var.missing()) { bin_path = bin_path_var; - } - else - { - if (contains(PREFIX L"/bin", L"/bin", L"/usr/bin")) - { + } else { + if (contains(PREFIX L"/bin", L"/bin", L"/usr/bin")) { bin_path = L"/bin" ARRAY_SEP_STR L"/usr/bin"; - } - else - { + } else { bin_path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin"; } } wcstring nxt_path; wcstokenizer tokenizer(bin_path, ARRAY_SEP_STR); - while (tokenizer.next(nxt_path)) - { - if (nxt_path.empty()) - continue; + while (tokenizer.next(nxt_path)) { + if (nxt_path.empty()) continue; append_path_component(nxt_path, cmd); - if (waccess(nxt_path, X_OK)==0) - { + if (waccess(nxt_path, X_OK) == 0) { struct stat buff; - if (wstat(nxt_path, &buff)==-1) - { - if (errno != EACCES) - { + if (wstat(nxt_path, &buff) == -1) { + if (errno != EACCES) { wperror(L"stat"); } continue; } - if (S_ISREG(buff.st_mode)) - { - if (out_path) - out_path->swap(nxt_path); + if (S_ISREG(buff.st_mode)) { + if (out_path) out_path->swap(nxt_path); return true; } err = EACCES; - } - else - { - switch (errno) - { + } else { + switch (errno) { case ENOENT: case ENAMETOOLONG: case EACCES: - case ENOTDIR: + case ENOTDIR: { break; - default: - { - debug(1, - MISSING_COMMAND_ERR_MSG, - nxt_path.c_str()); + } + default: { + debug(1, MISSING_COMMAND_ERR_MSG, nxt_path.c_str()); wperror(L"access"); } } @@ -124,69 +96,53 @@ static bool path_get_path_core(const wcstring &cmd, wcstring *out_path, const en return false; } -bool path_get_path(const wcstring &cmd, wcstring *out_path, const env_vars_snapshot_t &vars) -{ +bool path_get_path(const wcstring &cmd, wcstring *out_path, const env_vars_snapshot_t &vars) { return path_get_path_core(cmd, out_path, vars.get(L"PATH")); } -bool path_get_path(const wcstring &cmd, wcstring *out_path) -{ +bool path_get_path(const wcstring &cmd, wcstring *out_path) { return path_get_path_core(cmd, out_path, env_get_string(L"PATH")); } -bool path_get_cdpath(const wcstring &dir, wcstring *out, const wchar_t *wd, const env_vars_snapshot_t &env_vars) -{ +bool path_get_cdpath(const wcstring &dir, wcstring *out, const wchar_t *wd, + const env_vars_snapshot_t &env_vars) { int err = ENOENT; - if (dir.empty()) - return false; + if (dir.empty()) return false; - if (wd) - { + if (wd) { size_t len = wcslen(wd); assert(wd[len - 1] == L'/'); } wcstring_list_t paths; - if (dir.at(0) == L'/') - { - /* Absolute path */ + if (dir.at(0) == L'/') { + // Absolute path. paths.push_back(dir); - } - else if (string_prefixes_string(L"./", dir) || - string_prefixes_string(L"../", dir) || - dir == L"." || dir == L"..") - { - /* Path is relative to the working directory */ + } else if (string_prefixes_string(L"./", dir) || string_prefixes_string(L"../", dir) || + dir == L"." || dir == L"..") { + // Path is relative to the working directory. wcstring path; - if (wd) - path.append(wd); + if (wd) path.append(wd); path.append(dir); paths.push_back(path); - } - else - { - // Respect CDPATH + } else { + // Respect CDPATH. env_var_t path = env_vars.get(L"CDPATH"); - if (path.missing_or_empty()) - path = L"."; //We'll change this to the wd if we have one + if (path.missing_or_empty()) path = L"."; // we'll change this to the wd if we have one wcstring nxt_path; wcstokenizer tokenizer(path, ARRAY_SEP_STR); - while (tokenizer.next(nxt_path)) - { - - if (nxt_path == L"." && wd != NULL) - { - // nxt_path is just '.', and we have a working directory, so use the wd instead - // TODO: if nxt_path starts with ./ we need to replace the . with the wd + while (tokenizer.next(nxt_path)) { + if (nxt_path == L"." && wd != NULL) { + // nxt_path is just '.', and we have a working directory, so use the wd instead. + // TODO: if nxt_path starts with ./ we need to replace the . with the wd. nxt_path = wd; } expand_tilde(nxt_path); -// debug( 2, L"woot %ls\n", expanded_path.c_str() ); + // debug( 2, L"woot %ls\n", expanded_path.c_str() ); - if (nxt_path.empty()) - continue; + if (nxt_path.empty()) continue; wcstring whole_path = nxt_path; append_path_component(whole_path, dir); @@ -195,300 +151,245 @@ bool path_get_cdpath(const wcstring &dir, wcstring *out, const wchar_t *wd, cons } bool success = false; - for (wcstring_list_t::const_iterator iter = paths.begin(); iter != paths.end(); ++iter) - { + for (wcstring_list_t::const_iterator iter = paths.begin(); iter != paths.end(); ++iter) { struct stat buf; const wcstring &dir = *iter; - if (wstat(dir, &buf) == 0) - { - if (S_ISDIR(buf.st_mode)) - { + if (wstat(dir, &buf) == 0) { + if (S_ISDIR(buf.st_mode)) { success = true; - if (out) - out->assign(dir); + if (out) out->assign(dir); break; - } - else - { + } else { err = ENOTDIR; } } } - if (! success) - errno = err; + if (!success) errno = err; return success; } -bool path_can_be_implicit_cd(const wcstring &path, wcstring *out_path, const wchar_t *wd, const env_vars_snapshot_t &vars) -{ +bool path_can_be_implicit_cd(const wcstring &path, wcstring *out_path, const wchar_t *wd, + const env_vars_snapshot_t &vars) { wcstring exp_path = path; expand_tilde(exp_path); bool result = false; - if (string_prefixes_string(L"/", exp_path) || - string_prefixes_string(L"./", exp_path) || - string_prefixes_string(L"../", exp_path) || - string_suffixes_string(L"/", exp_path) || - exp_path == L"..") - { - /* These paths can be implicit cd, so see if you cd to the path. Note that a single period cannot (that's used for sourcing files anyways) */ + if (string_prefixes_string(L"/", exp_path) || string_prefixes_string(L"./", exp_path) || + string_prefixes_string(L"../", exp_path) || string_suffixes_string(L"/", exp_path) || + exp_path == L"..") { + // These paths can be implicit cd, so see if you cd to the path. Note that a single period + // cannot (that's used for sourcing files anyways). result = path_get_cdpath(exp_path, out_path, wd, vars); } return result; } -/* If the given path looks like it's relative to the working directory, then prepend that working directory. This operates on unescaped paths only (so a ~ means a literal ~) */ -wcstring path_apply_working_directory(const wcstring &path, const wcstring &working_directory) -{ - if (path.empty() || working_directory.empty()) - return path; - - /* We're going to make sure that if we want to prepend the wd, that the string has no leading / */ +// If the given path looks like it's relative to the working directory, then prepend that working +// directory. This operates on unescaped paths only (so a ~ means a literal ~). +wcstring path_apply_working_directory(const wcstring &path, const wcstring &working_directory) { + if (path.empty() || working_directory.empty()) return path; + + // We're going to make sure that if we want to prepend the wd, that the string has no leading + // "/". bool prepend_wd; - switch (path.at(0)) - { + switch (path.at(0)) { case L'/': - case HOME_DIRECTORY: + case HOME_DIRECTORY: { prepend_wd = false; break; - default: + } + default: { prepend_wd = true; break; + } } - - if (! prepend_wd) - { - /* No need to prepend the wd, so just return the path we were given */ + + if (!prepend_wd) { + // No need to prepend the wd, so just return the path we were given. return path; - } - else - { - /* Remove up to one ./ */ + } else { + // Remove up to one "./". wcstring path_component = path; - if (string_prefixes_string(L"./", path_component)) - { + if (string_prefixes_string(L"./", path_component)) { path_component.erase(0, 2); } - - /* Removing leading /s */ - while (string_prefixes_string(L"/", path_component)) - { + + // Removing leading /s. + while (string_prefixes_string(L"/", path_component)) { path_component.erase(0, 1); } - - /* Construct and return a new path */ + + // Construct and return a new path. wcstring new_path = working_directory; append_path_component(new_path, path_component); return new_path; } } - - -static wcstring path_create_config() -{ +static wcstring path_create_config() { bool done = false; wcstring res; - const env_var_t xdg_dir = env_get_string(L"XDG_CONFIG_HOME"); - if (! xdg_dir.missing()) - { + const env_var_t xdg_dir = env_get_string(L"XDG_CONFIG_HOME"); + if (!xdg_dir.missing()) { res = xdg_dir + L"/fish"; - if (!create_directory(res)) - { + if (!create_directory(res)) { done = true; } - } - else - { + } else { const env_var_t home = env_get_string(L"HOME"); - if (! home.missing()) - { + if (!home.missing()) { res = home + L"/.config/fish"; - if (!create_directory(res)) - { + if (!create_directory(res)) { done = true; } } } - if (! done) - { + if (!done) { res.clear(); - debug(0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access.")); + debug(0, _(L"Unable to create a configuration directory for fish. Your personal settings " + L"will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory " + L"where the current user has write access.")); } return res; } -static wcstring path_create_data() -{ +static wcstring path_create_data() { bool done = false; wcstring res; - const env_var_t xdg_dir = env_get_string(L"XDG_DATA_HOME"); - if (! xdg_dir.missing()) - { + const env_var_t xdg_dir = env_get_string(L"XDG_DATA_HOME"); + if (!xdg_dir.missing()) { res = xdg_dir + L"/fish"; - if (!create_directory(res)) - { + if (!create_directory(res)) { done = true; } - } - else - { + } else { const env_var_t home = env_get_string(L"HOME"); - if (! home.missing()) - { + if (!home.missing()) { res = home + L"/.local/share/fish"; - if (!create_directory(res)) - { + if (!create_directory(res)) { done = true; } } } - if (! done) - { + if (!done) { res.clear(); - debug(0, _(L"Unable to create a data directory for fish. Your history will not be saved. Please set the $XDG_DATA_HOME variable to a directory where the current user has write access.")); + debug(0, _(L"Unable to create a data directory for fish. Your history will not be saved. " + L"Please set the $XDG_DATA_HOME variable to a directory where the current user " + L"has write access.")); } return res; } -/* Cache the config path */ -bool path_get_config(wcstring &path) -{ +/// Cache the config path. +bool path_get_config(wcstring &path) { static const wcstring result = path_create_config(); path = result; - return ! result.empty(); + return !result.empty(); } -/* Cache the data path */ -bool path_get_data(wcstring &path) -{ +/// Cache the data path. +bool path_get_data(wcstring &path) { static const wcstring result = path_create_data(); path = result; - return ! result.empty(); + return !result.empty(); } -__attribute__((unused)) -static void replace_all(wcstring &str, const wchar_t *needle, const wchar_t *replacement) -{ +__attribute__((unused)) static void replace_all(wcstring &str, const wchar_t *needle, + const wchar_t *replacement) { size_t needle_len = wcslen(needle); size_t offset = 0; - while ((offset = str.find(needle, offset)) != wcstring::npos) - { + while ((offset = str.find(needle, offset)) != wcstring::npos) { str.replace(offset, needle_len, replacement); offset += needle_len; } } -void path_make_canonical(wcstring &path) -{ - // Ignore trailing slashes, unless it's the first character +void path_make_canonical(wcstring &path) { + // Ignore trailing slashes, unless it's the first character. size_t len = path.size(); - while (len > 1 && path.at(len - 1) == L'/') - len--; + while (len > 1 && path.at(len - 1) == L'/') len--; - // Turn runs of slashes into a single slash + // Turn runs of slashes into a single slash. size_t trailing = 0; bool prev_was_slash = false; - for (size_t leading = 0; leading < len; leading++) - { + for (size_t leading = 0; leading < len; leading++) { wchar_t c = path.at(leading); bool is_slash = (c == '/'); - if (! prev_was_slash || ! is_slash) - { - // This is either the first slash in a run, or not a slash at all + if (!prev_was_slash || !is_slash) { + // This is either the first slash in a run, or not a slash at all. path.at(trailing++) = c; } prev_was_slash = is_slash; } assert(trailing <= len); - if (trailing < len) - path.resize(trailing); + if (trailing < len) path.resize(trailing); } -bool paths_are_equivalent(const wcstring &p1, const wcstring &p2) -{ - if (p1 == p2) - return true; +bool paths_are_equivalent(const wcstring &p1, const wcstring &p2) { + if (p1 == p2) return true; size_t len1 = p1.size(), len2 = p2.size(); - // Ignore trailing slashes after the first character + // Ignore trailing slashes after the first character. while (len1 > 1 && p1.at(len1 - 1) == L'/') len1--; while (len2 > 1 && p2.at(len2 - 1) == L'/') len2--; // Start walking size_t idx1 = 0, idx2 = 0; - while (idx1 < len1 && idx2 < len2) - { + while (idx1 < len1 && idx2 < len2) { wchar_t c1 = p1.at(idx1), c2 = p2.at(idx2); - // If the characters are different, the strings are not equivalent - if (c1 != c2) - break; + // If the characters are different, the strings are not equivalent. + if (c1 != c2) break; idx1++; idx2++; - // If the character was a slash, walk forwards until we hit the end of the string, or a non-slash - // Note the first condition is invariant within the loop + // If the character was a slash, walk forwards until we hit the end of the string, or a + // non-slash. Note the first condition is invariant within the loop. while (c1 == L'/' && idx1 < len1 && p1.at(idx1) == L'/') idx1++; while (c2 == L'/' && idx2 < len2 && p2.at(idx2) == L'/') idx2++; } - // We matched if we consumed all of the characters in both strings + // We matched if we consumed all of the characters in both strings. return idx1 == len1 && idx2 == len2; } -bool path_is_valid(const wcstring &path, const wcstring &working_directory) -{ +bool path_is_valid(const wcstring &path, const wcstring &working_directory) { bool path_is_valid; - /* Some special paths are always valid */ - if (path.empty()) - { + // Some special paths are always valid. + if (path.empty()) { path_is_valid = false; - } - else if (path == L"." || path == L"./") - { + } else if (path == L"." || path == L"./") { path_is_valid = true; - } - else if (path == L".." || path == L"../") - { - path_is_valid = (! working_directory.empty() && working_directory != L"/"); - } - else if (path.at(0) != '/') - { - /* Prepend the working directory. Note that we know path is not empty here. */ + } else if (path == L".." || path == L"../") { + path_is_valid = (!working_directory.empty() && working_directory != L"/"); + } else if (path.at(0) != '/') { + // Prepend the working directory. Note that we know path is not empty here. wcstring tmp = working_directory; tmp.append(path); path_is_valid = (0 == waccess(tmp, F_OK)); - } - else - { - /* Simple check */ + } else { + // Simple check. path_is_valid = (0 == waccess(path, F_OK)); } return path_is_valid; } -bool paths_are_same_file(const wcstring &path1, const wcstring &path2) -{ - if (paths_are_equivalent(path1, path2)) - return true; +bool paths_are_same_file(const wcstring &path1, const wcstring &path2) { + if (paths_are_equivalent(path1, path2)) return true; struct stat s1, s2; - if (wstat(path1, &s1) == 0 && wstat(path2, &s2) == 0) - { + if (wstat(path1, &s1) == 0 && wstat(path2, &s2) == 0) { return s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev; - } - else - { + } else { return false; } } @@ -1,103 +1,86 @@ -/** \file path.h - - Directory utilities. This library contains functions for locating - configuration directories, for testing if a command with a given - name can be found in the PATH, and various other path-related - issues. -*/ +// Directory utilities. This library contains functions for locating configuration directories, for +// testing if a command with a given name can be found in the PATH, and various other path-related +// issues. #ifndef FISH_PATH_H #define FISH_PATH_H -#include <stddef.h> #include <stdbool.h> +#include <stddef.h> #include "common.h" #include "env.h" -/** - Return value for path_cdpath_get when locatied a rotten symlink - */ +/// Return value for path_cdpath_get when locatied a rotten symlink. #define EROTTEN 1 -/** - Returns the user configuration directory for fish. If the directory - or one of its parents doesn't exist, they are first created. - - \param path The directory as an out param - \return whether the directory was returned successfully -*/ +/// Returns the user configuration directory for fish. If the directory or one of its parents +/// doesn't exist, they are first created. +/// +/// \param path The directory as an out param +/// \return whether the directory was returned successfully bool path_get_config(wcstring &path); -/** - Returns the user data directory for fish. If the directory - or one of its parents doesn't exist, they are first created. - - Volatile files presumed to be local to the machine, - such as the fish_history and all the generated_completions, - will be stored in this directory. - - \param path The directory as an out param - \return whether the directory was returned successfully -*/ +/// Returns the user data directory for fish. If the directory or one of its parents doesn't exist, +/// they are first created. +/// +/// Volatile files presumed to be local to the machine, such as the fish_history and all the +/// generated_completions, will be stored in this directory. +/// +/// \param path The directory as an out param +/// \return whether the directory was returned successfully bool path_get_data(wcstring &path); -/** - Finds the full path of an executable. Returns YES if successful. - - \param cmd The name of the executable. - \param output_or_NULL If non-NULL, store the full path. - \param vars The environment variables snapshot to use - \return 0 if the command can not be found, the path of the command otherwise. The result should be freed with free(). -*/ -bool path_get_path(const wcstring &cmd, - wcstring *output_or_NULL, +/// Finds the full path of an executable. Returns YES if successful. +/// +/// \param cmd The name of the executable. +/// \param output_or_NULL If non-NULL, store the full path. +/// \param vars The environment variables snapshot to use +/// \return 0 if the command can not be found, the path of the command otherwise. The result should +/// be freed with free(). +bool path_get_path(const wcstring &cmd, wcstring *output_or_NULL, const env_vars_snapshot_t &vars = env_vars_snapshot_t::current()); -/** - Returns the full path of the specified directory, using the CDPATH - variable as a list of base directories for relative paths. The - returned string is allocated using halloc and the specified - context. - - If no valid path is found, null is returned and errno is set to - ENOTDIR if at least one such path was found, but it did not point - to a directory, EROTTEN if a arotten symbolic link was found, or - ENOENT if no file of the specified name was found. If both a rotten - symlink and a file are found, it is undefined which error status - will be returned. - - \param dir The name of the directory. - \param out_or_NULL If non-NULL, return the path to the resolved directory - \param wd The working directory, or NULL to use the default. The working directory should have a slash appended at the end. - \param vars The environment variable snapshot to use (for the CDPATH variable) - \return 0 if the command can not be found, the path of the command otherwise. The path should be free'd with free(). -*/ -bool path_get_cdpath(const wcstring &dir, - wcstring *out_or_NULL, - const wchar_t *wd = NULL, +/// Returns the full path of the specified directory, using the CDPATH variable as a list of base +/// directories for relative paths. The returned string is allocated using halloc and the specified +/// context. +/// +/// If no valid path is found, null is returned and errno is set to ENOTDIR if at least one such +/// path was found, but it did not point to a directory, EROTTEN if a arotten symbolic link was +/// found, or ENOENT if no file of the specified name was found. If both a rotten symlink and a file +/// are found, it is undefined which error status will be returned. +/// +/// \param dir The name of the directory. +/// \param out_or_NULL If non-NULL, return the path to the resolved directory +/// \param wd The working directory, or NULL to use the default. The working directory should have a +/// slash appended at the end. +/// \param vars The environment variable snapshot to use (for the CDPATH variable) +/// \return 0 if the command can not be found, the path of the command otherwise. The path should be +/// free'd with free(). +bool path_get_cdpath(const wcstring &dir, wcstring *out_or_NULL, const wchar_t *wd = NULL, const env_vars_snapshot_t &vars = env_vars_snapshot_t::current()); -/** Returns whether the path can be used for an implicit cd command; if so, also returns the path by reference (if desired). This requires it to start with one of the allowed prefixes (., .., ~) and resolve to a directory. */ -bool path_can_be_implicit_cd(const wcstring &path, - wcstring *out_path = NULL, +/// Returns whether the path can be used for an implicit cd command; if so, also returns the path by +/// reference (if desired). This requires it to start with one of the allowed prefixes (., .., ~) +/// and resolve to a directory. +bool path_can_be_implicit_cd(const wcstring &path, wcstring *out_path = NULL, const wchar_t *wd = NULL, const env_vars_snapshot_t &vars = env_vars_snapshot_t::current()); -/** - Remove double slashes and trailing slashes from a path, - e.g. transform foo//bar/ into foo/bar. The string is modified in-place. - */ +/// Remove double slashes and trailing slashes from a path, e.g. transform foo//bar/ into foo/bar. +/// The string is modified in-place. void path_make_canonical(wcstring &path); -/** Check if two paths are equivalent, which means to ignore runs of multiple slashes (or trailing slashes) */ +/// Check if two paths are equivalent, which means to ignore runs of multiple slashes (or trailing +/// slashes). bool paths_are_equivalent(const wcstring &p1, const wcstring &p2); bool path_is_valid(const wcstring &path, const wcstring &working_directory); -/** Returns whether the two paths refer to the same file */ +/// Returns whether the two paths refer to the same file. bool paths_are_same_file(const wcstring &path1, const wcstring &path2); -/* If the given path looks like it's relative to the working directory, then prepend that working directory. This operates on unescaped paths only (so a ~ means a literal ~) */ +/// If the given path looks like it's relative to the working directory, then prepend that working +/// directory. This operates on unescaped paths only (so a ~ means a literal ~). wcstring path_apply_working_directory(const wcstring &path, const wcstring &working_directory); #endif |