+/* A class to wrap up the logic for finding the three different types of
+ initialisation files GDB uses, system wide, home directory, and current
+ working directory. */
+
+class gdb_initfile_finder
+{
+public:
+ /* Constructor. Finds initialisation files named FILENAME in the home
+ directory or local (current working) directory. System initialisation
+ files are found in both SYSTEM_FILENAME and SYSTEM_DIRNAME if these
+ are not nullptr (either or both can be). The matching *_RELOCATABLE
+ flag is passed through to RELOCATE_FILE_PATH_MAYBE_IN_DATADIR.
+
+ If FILENAME starts with a '.' then when looking in the home directory
+ this first '.' can be ignored in some cases. */
+ explicit gdb_initfile_finder (const char *filename,
+ const char *system_filename,
+ bool system_filename_relocatable,
+ const char *system_dirname,
+ bool system_dirname_relocatable,
+ bool lookup_local_file)
+ {
+ struct stat s;
+
+ if (system_filename != nullptr && system_filename[0] != '\0')
+ {
+ std::string relocated_filename
+ = relocate_file_path_maybe_in_datadir (system_filename,
+ system_filename_relocatable);
+ if (!relocated_filename.empty ()
+ && stat (relocated_filename.c_str (), &s) == 0)
+ m_system_files.push_back (relocated_filename);
+ }
+
+ if (system_dirname != nullptr && system_dirname[0] != '\0')
+ {
+ std::string relocated_dirname
+ = relocate_file_path_maybe_in_datadir (system_dirname,
+ system_dirname_relocatable);
+ if (!relocated_dirname.empty ())
+ {
+ gdb_dir_up dir (opendir (relocated_dirname.c_str ()));
+ if (dir != nullptr)
+ {
+ std::vector<std::string> files;
+ while (true)
+ {
+ struct dirent *ent = readdir (dir.get ());
+ if (ent == nullptr)
+ break;
+ std::string name (ent->d_name);
+ if (name == "." || name == "..")
+ continue;
+ /* ent->d_type is not available on all systems
+ (e.g. mingw, Solaris), so we have to call stat(). */
+ std::string tmp_filename
+ = relocated_dirname + SLASH_STRING + name;
+ if (stat (tmp_filename.c_str (), &s) != 0
+ || !S_ISREG (s.st_mode))
+ continue;
+ const struct extension_language_defn *extlang
+ = get_ext_lang_of_file (tmp_filename.c_str ());
+ /* We effectively don't support "set script-extension
+ off/soft", because we are loading system init files
+ here, so it does not really make sense to depend on
+ a setting. */
+ if (extlang != nullptr && ext_lang_present_p (extlang))
+ files.push_back (std::move (tmp_filename));
+ }
+ std::sort (files.begin (), files.end ());
+ m_system_files.insert (m_system_files.end (),
+ files.begin (), files.end ());
+ }
+ }
+ }