int function_exists_no_autoload( const wcstring &cmd, const env_vars_snapshot_t &vars ) { if( parser_keywords_is_reserved(cmd) ) return 0; scoped_lock lock(functions_lock); return loaded_functions.find(cmd) != loaded_functions.end() || function_autoloader.can_load(cmd, vars); }
int function_exists( const wcstring &cmd ) { if( parser_keywords_is_reserved(cmd) ) return 0; scoped_lock lock(functions_lock); load(cmd); return loaded_functions.find(cmd) != loaded_functions.end(); }
void function_set_desc(const wcstring &name, const wcstring &desc) { load(name); scoped_lock locker(functions_lock); function_map_t::iterator iter = loaded_functions.find(name); if (iter != loaded_functions.end()) { iter->second.description = desc; } }
static const function_info_t *function_get(const wcstring &name) { // The caller must lock the functions_lock before calling this; however our mutex is currently // recursive, so trylock will never fail. We need a way to correctly check if a lock is locked // (or better yet, make our lock non-recursive). // ASSERT_IS_LOCKED(functions_lock); function_map_t::iterator iter = loaded_functions.find(name); if (iter == loaded_functions.end()) { return NULL; } return &iter->second; }
bool function_copy(const wcstring &name, const wcstring &new_name) { bool result = false; scoped_lock lock(functions_lock); function_map_t::const_iterator iter = loaded_functions.find(name); if (iter != loaded_functions.end()) { // This new instance of the function shouldn't be tied to the definition file of the original, so pass NULL filename, etc. const function_map_t::value_type new_pair(new_name, function_info_t(iter->second, NULL, 0, false)); loaded_functions.insert(new_pair); result = true; } return result; }
/** Make sure that if the specified function is a dynamically loaded function, it has been fully loaded. */ static int load( const wcstring &name ) { ASSERT_IS_MAIN_THREAD(); scoped_lock lock(functions_lock); bool was_autoload = is_autoload; int res; function_map_t::iterator iter = loaded_functions.find(name); if( iter != loaded_functions.end() && !iter->second.is_autoload ) { /* We have a non-autoload version already */ return 0; } is_autoload = true; res = function_autoloader.load( name, true ); is_autoload = was_autoload; return res; }
wcstring_list_t function_get_names(int get_hidden) { std::set<wcstring> names; scoped_lock locker(functions_lock); autoload_names(names, get_hidden); function_map_t::const_iterator iter; for (iter = loaded_functions.begin(); iter != loaded_functions.end(); ++iter) { const wcstring &name = iter->first; // Maybe skip hidden. if (!get_hidden) { if (name.empty() || name.at(0) == L'_') continue; } names.insert(name); } return wcstring_list_t(names.begin(), names.end()); }
static bool function_remove_ignore_autoload(const wcstring &name, bool tombstone) { // Note: the lock may be held at this point, but is recursive. scoped_lock locker(functions_lock); function_map_t::iterator iter = loaded_functions.find(name); // Not found. Not erasing. if (iter == loaded_functions.end()) return false; // Removing an auto-loaded function. Prevent it from being auto-reloaded. if (iter->second.is_autoload && tombstone) function_tombstones.insert(name); loaded_functions.erase(iter); event_t ev(EVENT_ANY); ev.function_name = name; event_remove(ev); return true; }
/// Make sure that if the specified function is a dynamically loaded function, it has been fully /// loaded. static int load(const wcstring &name) { ASSERT_IS_MAIN_THREAD(); scoped_lock locker(functions_lock); bool was_autoload = is_autoload; int res; bool no_more_autoload = function_tombstones.count(name) > 0; if (no_more_autoload) return 0; function_map_t::iterator iter = loaded_functions.find(name); if (iter != loaded_functions.end() && !iter->second.is_autoload) { // We have a non-autoload version already. return 0; } is_autoload = true; res = function_autoloader.load(name, true); is_autoload = was_autoload; return res; }