2012-01-25 00:36:55 -08:00
/** \file autoload.h
The classes responsible for autoloading functions and completions .
*/
2012-01-25 11:47:45 -08:00
# ifndef FISH_AUTOLOAD_H
# define FISH_AUTOLOAD_H
2012-01-25 00:36:55 -08:00
# include <wchar.h>
# include <map>
# include <set>
# include <list>
# include "common.h"
2012-02-05 20:54:41 -08:00
# include "lru.h"
2012-01-25 00:36:55 -08:00
2012-01-25 11:47:45 -08:00
/** A struct responsible for recording an attempt to access a file. */
2012-11-18 16:30:30 -08:00
struct file_access_attempt_t
{
2012-01-25 00:36:55 -08:00
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 */
} ;
2012-01-25 11:47:45 -08:00
file_access_attempt_t access_file ( const wcstring & path , int mode ) ;
2012-01-25 00:36:55 -08:00
2012-01-25 18:59:35 -08:00
struct autoload_function_t : public lru_node_t
2012-11-18 11:23:22 +01:00
{
2012-02-26 20:11:34 -08:00
autoload_function_t ( const wcstring & key ) : lru_node_t ( key ) , access ( ) , is_loaded ( false ) , is_placeholder ( false ) , is_internalized ( false ) { }
2012-01-25 18:59:35 -08:00
file_access_attempt_t access ; /** The last access attempt */
2012-01-27 11:43:52 -08:00
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. */
2012-02-26 20:11:34 -08:00
bool is_internalized ; /** Whether this function came from a builtin "internalized" script */
2012-01-25 18:59:35 -08:00
} ;
2012-12-10 16:23:08 -08:00
struct builtin_script_t
{
const wchar_t * name ;
const char * def ;
2012-12-08 21:41:38 -08:00
} ;
2012-01-25 18:59:35 -08:00
struct builtin_script_t ;
2012-07-20 20:39:31 -07:00
class env_vars_snapshot_t ;
2012-01-25 18:59:35 -08:00
/**
A class that represents a path from which we can autoload , and the autoloaded contents .
*/
2012-11-18 16:30:30 -08:00
class autoload_t : private lru_cache_t < autoload_function_t >
{
2012-01-25 18:59:35 -08:00
private :
2012-01-28 14:56:13 -08:00
/** Lock for thread safety */
pthread_mutex_t lock ;
2012-01-25 18:59:35 -08:00
/** The environment variable name */
const wcstring env_var_name ;
2012-11-18 11:23:22 +01:00
2012-01-25 18:59:35 -08:00
/** Builtin script array */
const struct builtin_script_t * const builtin_scripts ;
2012-11-18 11:23:22 +01:00
2012-01-25 18:59:35 -08:00
/** Builtin script count */
const size_t builtin_script_count ;
/** The path from which we most recently autoloaded */
2012-03-31 15:17:14 -07:00
wcstring last_path ;
2012-01-25 18:59:35 -08:00
2012-11-18 16:30:30 -08:00
/**
A table containing all the files that are currently being
loaded . This is here to help prevent recursion .
*/
2012-01-25 18:59:35 -08:00
std : : set < wcstring > is_loading_set ;
2012-11-18 16:30:30 -08:00
bool is_loading ( const wcstring & name ) const
{
2012-01-25 18:59:35 -08:00
return is_loading_set . find ( name ) ! = is_loading_set . end ( ) ;
}
2012-11-18 11:23:22 +01:00
2012-11-18 16:30:30 -08:00
void remove_all_functions ( void )
{
2012-01-27 11:43:52 -08:00
this - > evict_all_nodes ( ) ;
2012-01-25 18:59:35 -08:00
}
2012-11-18 11:23:22 +01:00
2012-11-18 16:30:30 -08:00
bool locate_file_and_maybe_load_it ( const wcstring & cmd , bool really_load , bool reload , const wcstring_list_t & path_list ) ;
2012-11-18 11:23:22 +01:00
2012-01-25 18:59:35 -08:00
virtual void node_was_evicted ( autoload_function_t * node ) ;
2012-02-26 20:11:34 -08:00
autoload_function_t * get_autoloaded_function_with_creation ( const wcstring & cmd , bool allow_eviction ) ;
2012-11-18 11:23:22 +01:00
2012-11-18 16:30:30 -08:00
protected :
2012-01-25 18:59:35 -08:00
/** Overridable callback for when a command is removed */
virtual void command_removed ( const wcstring & cmd ) { }
2012-11-18 11:23:22 +01:00
2012-11-18 16:30:30 -08:00
public :
2012-11-18 11:23:22 +01:00
2012-01-25 18:59:35 -08:00
/** Create an autoload_t for the given environment variable name */
2012-11-18 16:30:30 -08:00
autoload_t ( const wcstring & env_var_name_var , const builtin_script_t * scripts , size_t script_count ) ;
2012-11-18 11:23:22 +01:00
2012-01-28 14:56:13 -08:00
/** Destructor */
virtual ~ autoload_t ( ) ;
2012-11-18 11:23:22 +01:00
2012-01-25 18:59:35 -08:00
/**
Autoload the specified file , if it exists in the specified path . Do
2012-11-23 11:25:33 -08:00
not load it multiple times unless its timestamp changes or
2012-01-25 18:59:35 -08:00
parse_util_unload is called .
2012-11-18 11:23:22 +01:00
Autoloading one file may unload another .
2012-01-25 18:59:35 -08:00
\ 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
*/
2012-11-18 16:30:30 -08:00
int load ( const wcstring & cmd , bool reload ) ;
2012-11-18 11:23:22 +01:00
2012-02-26 20:11:34 -08:00
/** Check whether we have tried loading the given command. Does not do any I/O. */
2012-11-18 16:30:30 -08:00
bool has_tried_loading ( const wcstring & cmd ) ;
2012-01-25 18:59:35 -08:00
/**
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
*/
2012-11-18 16:30:30 -08:00
int unload ( const wcstring & cmd ) ;
2012-11-18 11:23:22 +01:00
2012-01-27 11:43:52 -08:00
/**
Unloads all files .
*/
2012-11-18 16:30:30 -08:00
void unload_all ( ) ;
2012-11-18 11:23:22 +01:00
2012-01-27 11:43:52 -08:00
/** Check whether the given command could be loaded, but do not load it. */
2012-11-18 16:30:30 -08:00
bool can_load ( const wcstring & cmd , const env_vars_snapshot_t & vars ) ;
2012-01-25 18:59:35 -08:00
} ;
2012-01-25 00:36:55 -08:00
# endif