mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-12 00:03:39 +08:00
96 lines
3.6 KiB
C++
96 lines
3.6 KiB
C++
// The classes responsible for autoloading functions and completions.
|
|
#ifndef FISH_AUTOLOAD_H
|
|
#define FISH_AUTOLOAD_H
|
|
|
|
#include <pthread.h>
|
|
#include <time.h>
|
|
|
|
#include <set>
|
|
#include <unordered_set>
|
|
|
|
#include "common.h"
|
|
#include "env.h"
|
|
#include "lru.h"
|
|
|
|
/// Record of an attempt to access a file.
|
|
struct file_access_attempt_t {
|
|
/// Modification time of the file
|
|
time_t mod_time;
|
|
/// When we last checked the file
|
|
time_t last_checked;
|
|
/// Whether or not we believe we can access this file
|
|
bool accessible;
|
|
/// The access attempt is stale
|
|
bool stale;
|
|
/// If we cannot access the file, the error code encountered.
|
|
int error;
|
|
};
|
|
file_access_attempt_t access_file(const wcstring &path, int mode);
|
|
|
|
struct autoload_function_t {
|
|
explicit autoload_function_t(bool placeholder)
|
|
: access(), is_loaded(false), is_placeholder(placeholder) {}
|
|
|
|
/// The last access attempt recorded
|
|
file_access_attempt_t access;
|
|
/// Have we actually loaded this function?
|
|
bool is_loaded;
|
|
/// Whether we are a placeholder that stands in for "no such function". If this is true, then
|
|
/// is_loaded must be false.
|
|
bool is_placeholder;
|
|
};
|
|
|
|
class env_vars_snapshot_t;
|
|
|
|
/// Class representing a path from which we can autoload and the autoloaded contents.
|
|
class autoload_t : public lru_cache_t<autoload_t, autoload_function_t> {
|
|
private:
|
|
/// Lock for thread safety.
|
|
std::mutex lock;
|
|
/// The environment variable name.
|
|
const wcstring env_var_name;
|
|
/// The path from which we most recently autoloaded.
|
|
env_var_t last_path;
|
|
/// the most reecently autoloaded path, tokenized (split on separators).
|
|
wcstring_list_t last_path_tokenized;
|
|
/// A table containing all the files that are currently being loaded.
|
|
/// This is here to help prevent recursion.
|
|
std::unordered_set<wcstring> is_loading_set;
|
|
// Function invoked when a command is removed
|
|
typedef void (*command_removed_function_t)(const wcstring &);
|
|
const command_removed_function_t command_removed;
|
|
|
|
void remove_all_functions() { this->evict_all_nodes(); }
|
|
|
|
bool locate_file_and_maybe_load_it(const wcstring &cmd, bool really_load, bool reload,
|
|
const wcstring_list_t &path_list);
|
|
|
|
autoload_function_t *get_autoloaded_function_with_creation(const wcstring &cmd,
|
|
bool allow_eviction);
|
|
|
|
public:
|
|
// CRTP override
|
|
void entry_was_evicted(wcstring key, autoload_function_t node);
|
|
|
|
// Create an autoload_t for the given environment variable name.
|
|
autoload_t(const wcstring &env_var_name_var, command_removed_function_t callback);
|
|
|
|
/// Autoload the specified file, if it exists in the specified path. Do not load it multiple
|
|
/// times unless its timestamp changes or parse_util_unload is called.
|
|
/// Autoloading one file may unload another.
|
|
/// @param cmd the filename to search for. The suffix '.fish' is always added to this name
|
|
/// @param reload wheter to recheck file timestamps on already loaded files
|
|
int load(const wcstring &cmd, bool reload);
|
|
|
|
/// Check whether we have tried loading the given command. Does not do any I/O.
|
|
bool has_tried_loading(const wcstring &cmd);
|
|
|
|
/// Tell the autoloader that the specified file, in the specified path, is no longer loaded.
|
|
/// Returns non-zero if the file was removed, zero if the file had not yet been loaded
|
|
int unload(const wcstring &cmd);
|
|
|
|
/// Check whether the given command could be loaded, but do not load it.
|
|
bool can_load(const wcstring &cmd, const env_vars_snapshot_t &vars);
|
|
};
|
|
#endif
|