aboutsummaryrefslogtreecommitdiff
path: root/gdb/auto-load.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/auto-load.c')
-rw-r--r--gdb/auto-load.c80
1 files changed, 73 insertions, 7 deletions
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index 4fc5b08..f33a8d0 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -41,6 +41,7 @@
#include <algorithm>
#include "gdbsupport/pathstuff.h"
#include "cli/cli-style.h"
+#include "gdbsupport/selftest.h"
/* The section to look in for auto-loaded scripts (in file formats that
support sections).
@@ -162,6 +163,67 @@ show_auto_load_dir (struct ui_file *file, int from_tty,
value);
}
+/* Substitute all occurrences of string FROM by string TO in STRING.
+ STRING will be updated in place as needed. FROM needs to be
+ delimited by IS_DIR_SEPARATOR or DIRNAME_SEPARATOR (or be located
+ at the start or end of STRING. */
+
+static void
+substitute_path_component (std::string &string, std::string_view from,
+ std::string_view to)
+{
+ for (size_t s = 0;;)
+ {
+ s = string.find (from, s);
+ if (s == std::string::npos)
+ break;
+
+ if ((s == 0 || IS_DIR_SEPARATOR (string[s - 1])
+ || string[s - 1] == DIRNAME_SEPARATOR)
+ && (s + from.size () == string.size ()
+ || IS_DIR_SEPARATOR (string[s + from.size ()])
+ || string[s + from.size ()] == DIRNAME_SEPARATOR))
+ {
+ string.replace (s, from.size (), to);
+ s += to.size ();
+ }
+ else
+ s++;
+ }
+}
+
+#if GDB_SELF_TEST
+
+namespace selftests {
+namespace subst_path {
+
+static void
+test_substitute_path_component ()
+{
+ auto test = [] (std::string s, const char *from, const char *to,
+ const char *expected)
+ {
+ substitute_path_component (s, from, to);
+ SELF_CHECK (s == expected);
+ };
+
+ test ("/abc/$def/g", "abc", "xyz", "/xyz/$def/g");
+ test ("abc/$def/g", "abc", "xyz", "xyz/$def/g");
+ test ("/abc/$def/g", "$def", "xyz", "/abc/xyz/g");
+ test ("/abc/$def/g", "g", "xyz", "/abc/$def/xyz");
+ test ("/abc/$def/g", "ab", "xyz", "/abc/$def/g");
+ test ("/abc/$def/g", "def", "xyz", "/abc/$def/g");
+ test ("/abc/$def/g", "abc", "abc", "/abc/$def/g");
+ test ("/abc/$def/g", "abc", "", "//$def/g");
+ test ("/abc/$def/g", "abc/$def", "xyz", "/xyz/g");
+ test ("/abc/$def/abc", "abc", "xyz", "/xyz/$def/xyz");
+}
+
+}
+}
+
+#endif /* GDB_SELF_TEST */
+
/* Directory list safe to hold auto-loaded files. It is not checked for
absolute paths but they are strongly recommended. It is initialized by
_initialize_auto_load. */
@@ -178,16 +240,15 @@ static std::vector<gdb::unique_xmalloc_ptr<char>> auto_load_safe_path_vec;
static std::vector<gdb::unique_xmalloc_ptr<char>>
auto_load_expand_dir_vars (const char *string)
{
- char *s = xstrdup (string);
- substitute_path_component (&s, "$datadir", gdb_datadir.c_str ());
- substitute_path_component (&s, "$debugdir", debug_file_directory.c_str ());
+ std::string s = string;
+ substitute_path_component (s, "$datadir", gdb_datadir.c_str ());
+ substitute_path_component (s, "$debugdir", debug_file_directory.c_str ());
- if (debug_auto_load && strcmp (s, string) != 0)
- auto_load_debug_printf ("Expanded $-variables to \"%s\".", s);
+ if (debug_auto_load && s != string)
+ auto_load_debug_printf ("Expanded $-variables to \"%s\".", s.c_str ());
std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec
- = dirnames_to_char_ptr_vec (s);
- xfree(s);
+ = dirnames_to_char_ptr_vec (s.c_str ());
return dir_vec;
}
@@ -1650,4 +1711,9 @@ When non-zero, debugging output for files of 'set auto-load ...'\n\
is displayed."),
NULL, show_debug_auto_load,
&setdebuglist, &showdebuglist);
+
+#if GDB_SELF_TEST
+ selftests::register_test ("substitute_path_component",
+ selftests::subst_path::test_substitute_path_component);
+#endif
}