diff --git a/src/function.cpp b/src/function.cpp index f15b06739..bf32c2fe3 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -30,27 +30,26 @@ #include "wutil.h" // IWYU pragma: keep class function_info_t { -public: - /// Immutable properties of the function. - std::shared_ptr props; - /// Function description. This may be changed after the function is created. - wcstring description; - /// File where this function was defined (intern'd string). - const wchar_t *const definition_file; - /// Mapping of all variables that were inherited from the function definition scope to their - /// values. - const std::map inherit_vars; - /// Flag for specifying that this function was automatically loaded. - const bool is_autoload; + public: + /// Immutable properties of the function. + std::shared_ptr props; + /// Function description. This may be changed after the function is created. + wcstring description; + /// File where this function was defined (intern'd string). + const wchar_t *const definition_file; + /// Mapping of all variables that were inherited from the function definition scope to their + /// values. + const std::map inherit_vars; + /// Flag for specifying that this function was automatically loaded. + const bool is_autoload; - /// Constructs relevant information from the function_data. - function_info_t(function_data_t data, const wchar_t *filename, bool autoload); + /// Constructs relevant information from the function_data. + function_info_t(function_data_t data, const wchar_t *filename, bool autoload); - /// Used by function_copy. - function_info_t(const function_info_t &data, const wchar_t *filename, bool autoload); + /// Used by function_copy. + function_info_t(const function_info_t &data, const wchar_t *filename, bool autoload); }; - /// Table containing all functions. typedef std::unordered_map function_map_t; static function_map_t loaded_functions; @@ -110,12 +109,11 @@ static void autoload_names(std::unordered_set &names, int get_hidden) for (i = 0; i < path_list.size(); i++) { const wcstring &ndir_str = path_list.at(i); - const wchar_t *ndir = (wchar_t *)ndir_str.c_str(); - DIR *dir = wopendir(ndir); - if (!dir) continue; + dir_t dir(ndir_str); + if (!dir.valid()) continue; wcstring name; - while (wreaddir(dir, name)) { + while (dir.read(name)) { const wchar_t *fn = name.c_str(); const wchar_t *suffix; if (!get_hidden && fn[0] == L'_') continue; @@ -126,7 +124,6 @@ static void autoload_names(std::unordered_set &names, int get_hidden) names.insert(name); } } - closedir(dir); } } @@ -327,7 +324,8 @@ int function_get_definition_lineno(const wcstring &name) { scoped_rlock locker(functions_lock); const function_info_t *func = function_get(name); if (!func) return -1; - // return one plus the number of newlines at offsets less than the start of our function's statement (which includes the header). + // return one plus the number of newlines at offsets less than the start of our function's + // statement (which includes the header). // TODO: merge with line_offset_of_character_at_offset? auto block_stat = func->props->body_node.try_get_parent(); assert(block_stat && "Function body is not part of block statement"); diff --git a/src/wutil.cpp b/src/wutil.cpp index ee0bb03d6..51eaa44ca 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -235,6 +235,26 @@ DIR *wopendir(const wcstring &name) { return opendir(tmp.c_str()); } +dir_t::dir_t(const wcstring &path) { + const cstring tmp = wcs2string(path); + this->dir = opendir(tmp.c_str()); +} + +dir_t::~dir_t() { + if (this->dir != nullptr) { + closedir(this->dir); + this->dir = nullptr; + } +} + +bool dir_t::valid() const { + return this->dir != nullptr; +} + +bool dir_t::read(wcstring &name) { + return wreaddir(this->dir, name); +} + int wstat(const wcstring &file_name, struct stat *buf) { const cstring tmp = wcs2string(file_name); return stat(tmp.c_str(), buf); diff --git a/src/wutil.h b/src/wutil.h index c1af1e70e..055493432 100644 --- a/src/wutil.h +++ b/src/wutil.h @@ -152,6 +152,15 @@ struct file_id_t { int compare_file_id(const file_id_t &rhs) const; }; +/// RAII wrapper for DIR* +struct dir_t { + DIR *dir; + bool valid() const; + bool read(wcstring &name); + dir_t(const wcstring &path); + ~dir_t(); +}; + #ifndef HASH_FILE_ID #define HASH_FILE_ID 1 namespace std {