diff options
author | 2012-01-23 11:42:41 -0800 | |
---|---|---|
committer | 2012-01-23 11:42:41 -0800 | |
commit | 6e8637fbc98a7ff23696e6f9e0f53a465bcbcf22 (patch) | |
tree | 7410b542d5db999eb771e3e0447beb6f2a14a9a4 /parse_util.h | |
parent | 8403aae92886de1e0bd379c94b3715b6df6dc0e4 (diff) |
Move autoloading from a map of path names to a real object autoload_t.
Moved the various things we can autoload into static objects.
Next step is to make them thread safe.
Diffstat (limited to 'parse_util.h')
-rw-r--r-- | parse_util.h | 172 |
1 files changed, 130 insertions, 42 deletions
diff --git a/parse_util.h b/parse_util.h index 85b7ba3f..26e69363 100644 --- a/parse_util.h +++ b/parse_util.h @@ -8,6 +8,136 @@ #define FISH_PARSE_UTIL_H #include <wchar.h> +#include <map> +#include <set> + +struct autoload_function_t +{ + bool is_placeholder; //whether we are a placeholder that stands in for "no such function" + time_t modification_time; // st_mtime + time_t load_time; // when function was loaded + + + autoload_function_t() : is_placeholder(false), modification_time(0), load_time(0) { } +}; + +struct builtin_script_t; + +/** + A class that represents a path from which we can autoload, and the autoloaded contents. + */ +class autoload_t { +private: + /** 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 path; + + /** The map from function name to the function. */ + typedef std::map<wcstring, autoload_function_t> autoload_functions_map_t; + autoload_functions_map_t autoload_functions; + + /** + A table containing all the files that are currently being + loaded. This is here to help prevent recursion. + */ + std::set<wcstring> is_loading_set; + + bool is_loading(const wcstring &name) const { + return is_loading_set.find(name) != is_loading_set.end(); + } + + autoload_function_t *create_function_with_name(const wcstring &name) { + return &autoload_functions[name]; + } + + bool remove_function_with_name(const wcstring &name) { + return autoload_functions.erase(name) > 0; + } + + autoload_function_t *get_function_with_name(const wcstring &name) + { + autoload_function_t *result = NULL; + autoload_functions_map_t::iterator iter = autoload_functions.find(name); + if (iter != autoload_functions.end()) + result = &iter->second; + return result; + } + + void remove_all_functions(void) { + autoload_functions.clear(); + } + + size_t function_count(void) const { + return autoload_functions.size(); + } + + /** Returns the name of the function that was least recently loaded, if it was loaded before cutoff_access. Return NULL if no function qualifies. */ + const wcstring *get_lru_function_name(const wcstring &skip, time_t cutoff_access) const; + + int load_internal( const wcstring &cmd, void (*on_load)(const wchar_t *cmd), int reload, const wcstring_list_t &path_list ); + + /** + + Unload all autoloaded items that have expired, that where loaded in + the specified path. + + \param skip unloading the the specified file + \param on_load the callback function to call for every unloaded file + + */ + void autounload( const wchar_t *skip, + void (*on_load)(const wchar_t *cmd) ); + + void apply_handler_to_nonplaceholder_function_names(void (*handler)(const wchar_t *cmd)) const; + + 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 ); + + /** + Autoload the specified file, if it exists in the specified path. Do + not load it multiple times unless it's 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, + void (*on_unload)(const wchar_t *cmd), + int reload ); + /** + Reset the loader for the specified path variable. This will cause + all information on loaded files in the specified directory to be + reset. + + \param on_unload a callback function which will be called before (re)loading a file, may be used to unload the previous file. + */ + void reset( void (*on_unload)(const wchar_t *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 wchar_t *cmd, + void (*on_unload)(const wchar_t *cmd) ); + +}; /** Find the beginning and end of the first subshell in the specified string. @@ -109,48 +239,6 @@ int parse_util_get_offset_from_line( wchar_t *buff, int line ); */ int parse_util_get_offset( wchar_t *buff, int line, int line_offset ); - -/** - Autoload the specified file, if it exists in the specified path. Do - not load it multiple times unless it's 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 path_var_name the environment variable giving the search path - \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 parse_util_load( const wcstring &cmd, - const wcstring &path_var_name, - void (*on_unload)(const wchar_t *cmd), - int reload ); - -/** - Reset the loader for the specified path variable. This will cause - all information on loaded files in the specified directory to be - reset. - - \param path_var_name the environment variable giving the search path - \param on_unload a callback function which will be called before (re)loading a file, may be used to unload the previous file. -*/ -void parse_util_load_reset( const wchar_t *path_var_name, - void (*on_unload)(const wchar_t *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 path_var_name the environment variable giving the search path - \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 parse_util_unload( const wchar_t *cmd, - const wchar_t *path_var_name, - void (*on_unload)(const wchar_t *cmd) ); - /** Set the argv environment variable to the specified null-terminated array of strings. |