fish-shell/src/path.h
Aaron Gyes 14d2a6d8ff IWYU-guided #include rejiggering.
Let's hope this doesn't causes build failures for e.g. musl: I just
know it's good on macOS and our Linux CI.

It's been a long time.

One fix this brings, is I discovered we #include assert.h or cassert
in a lot of places. If those ever happen to be in a file that doesn't
include common.h, or we are before common.h gets included, we're
unawaringly working with the system 'assert' macro again, which
may get disabled for debug builds or at least has different
behavior on crash. We undef 'assert' and redefine it in common.h.

Those were all eliminated, except in one catch-22 spot for
maybe.h: it can't include common.h. A fix might be to
make a fish_assert.h that *usually* common.h exports.
2022-08-20 23:55:18 -07:00

110 lines
4.8 KiB
C++

// 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 <string>
#include "common.h"
#include "maybe.h"
/// 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
bool path_get_data(wcstring &path);
enum class dir_remoteness_t {
unknown, // directory status is unknown
local, // directory is known local
remote, // directory is known remote
};
/// \return the remoteness of the fish data directory.
/// This will be remote for filesystems like NFS, SMB, etc.
dir_remoteness_t path_get_data_remoteness();
/// Like path_get_data_remoteness but for the config directory.
dir_remoteness_t path_get_config_remoteness();
class env_stack_t;
/// Emit any errors if config directories are missing.
/// Use the given environment stack to ensure this only occurs once.
void path_emit_config_directory_messages(env_stack_t &vars);
class environment_t;
/// Finds the path of an executable named \p cmd, by looking in $PATH taken from \p vars.
/// \returns the path if found, none if not.
maybe_t<wcstring> path_get_path(const wcstring &cmd, const environment_t &vars);
/// Finds the path of an executable named \p cmd, by looking in $PATH taken from \p vars.
/// On success, err will be 0 and the path is returned.
/// On failure, we return the "best path" with err set appropriately.
/// For example, if we find a non-executable file, we will return its path and EACCESS.
/// If no candidate path is found, path will be empty and err will be set to ENOENT.
/// Possible err values are taken from access().
struct get_path_result_t {
int err;
wcstring path;
};
get_path_result_t path_try_get_path(const wcstring &cmd, const environment_t &vars);
/// Return all the paths that match the given command.
wcstring_list_t path_get_paths(const wcstring &cmd, const environment_t &vars);
/// Returns the full path of the specified directory, using the CDPATH variable as a list of base
/// directories for relative paths.
///
/// If no valid path is found, false is returned and errno is set to ENOTDIR if at least one such
/// path was found, but it did not point to a directory, or ENOENT if no file of the specified
/// name was found.
///
/// \param dir The name of the directory.
/// \param wd The working directory. The working directory must end with a slash.
/// \param vars The environment variables to use (for the CDPATH variable)
/// \return the command, or none() if it could not be found.
maybe_t<wcstring> path_get_cdpath(const wcstring &dir, const wcstring &wd,
const environment_t &vars);
/// Returns the given directory with all CDPATH components applied.
wcstring_list_t path_apply_cdpath(const wcstring &dir, const wcstring &wd,
const environment_t &env_vars);
/// Returns the path resolved as an implicit cd command, or none() if none. This requires it to
/// start with one of the allowed prefixes (., .., ~) and resolve to a directory.
maybe_t<wcstring> path_as_implicit_cd(const wcstring &path, const wcstring &wd,
const environment_t &vars);
/// 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).
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.
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 ~).
wcstring path_apply_working_directory(const wcstring &path, const wcstring &working_directory);
/// Appends a path component, with a / if necessary.
void append_path_component(wcstring &path, const wcstring &component);
#endif