From b4f53143b0e05fd3061cdf2e65e17a6a2904090b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 24 Jul 2015 00:50:58 -0700 Subject: Migrate source files into src/ directory This change moves source files into a src/ directory, and puts object files into an obj/ directory. The Makefile and xcode project are updated accordingly. Fixes #1866 --- src/autoload.h | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/autoload.h (limited to 'src/autoload.h') diff --git a/src/autoload.h b/src/autoload.h new file mode 100644 index 00000000..b4338538 --- /dev/null +++ b/src/autoload.h @@ -0,0 +1,136 @@ +/** \file autoload.h + + The classes responsible for autoloading functions and completions. +*/ + +#ifndef FISH_AUTOLOAD_H +#define FISH_AUTOLOAD_H + +#include +#include +#include +#include +#include "common.h" +#include "lru.h" + +/** A struct responsible for recording an attempt to access a file. */ +struct file_access_attempt_t +{ + time_t mod_time; /** The modification time of the file */ + time_t last_checked; /** When we last checked the file */ + bool accessible; /** Whether we believe we could access this file */ + bool stale; /** Whether the access attempt is stale */ + int error; /** If we could not access the file, the error code */ +}; + +file_access_attempt_t access_file(const wcstring &path, int mode); + +struct autoload_function_t : public lru_node_t +{ + autoload_function_t(const wcstring &key) : lru_node_t(key), access(), is_loaded(false), is_placeholder(false), is_internalized(false) { } + file_access_attempt_t access; /** The last access attempt */ + bool is_loaded; /** Whether we have actually loaded this function */ + bool is_placeholder; /** Whether we are a placeholder that stands in for "no such function". If this is true, then is_loaded must be false. */ + bool is_internalized; /** Whether this function came from a builtin "internalized" script */ +}; + +struct builtin_script_t +{ + const wchar_t *name; + const char *def; +}; + +struct builtin_script_t; +class env_vars_snapshot_t; + +/** + A class that represents a path from which we can autoload, and the autoloaded contents. + */ +class autoload_t : private lru_cache_t +{ +private: + + /** Lock for thread safety */ + pthread_mutex_t lock; + + /** The environment variable name */ + const wcstring env_var_name; + + /** Builtin script array */ + const struct builtin_script_t *const builtin_scripts; + + /** Builtin script count */ + const size_t builtin_script_count; + + /** The path from which we most recently autoloaded */ + wcstring last_path; + + /** That 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::set is_loading_set; + + void remove_all_functions(void) + { + 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); + + virtual void node_was_evicted(autoload_function_t *node); + + autoload_function_t *get_autoloaded_function_with_creation(const wcstring &cmd, bool allow_eviction); + +protected: + /** Overridable callback for when a command is removed */ + virtual void command_removed(const wcstring &cmd) { } + +public: + + /** Create an autoload_t for the given environment variable name */ + autoload_t(const wcstring &env_var_name_var, const builtin_script_t *scripts, size_t script_count); + + /** Destructor */ + virtual ~autoload_t(); + + /** + 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 on_unload a callback function to run if a suitable file is found, which has not already been run. unload will also be called for old files which are unloaded. + \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. + + \param cmd the filename to search for. The suffix '.fish' is always added to this name + \param on_unload a callback function which will be called before (re)loading a file, may be used to unload the previous file. + \return non-zero if the file was removed, zero if the file had not yet been loaded + */ + int unload(const wcstring &cmd); + + /** + Unloads all files. + */ + void unload_all(); + + /** 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 -- cgit v1.2.3