summaryrefslogtreecommitdiffstats
path: root/debian/patches/pr81829.diff
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/pr81829.diff')
-rw-r--r--debian/patches/pr81829.diff308
1 files changed, 308 insertions, 0 deletions
diff --git a/debian/patches/pr81829.diff b/debian/patches/pr81829.diff
new file mode 100644
index 0000000..472e3d0
--- /dev/null
+++ b/debian/patches/pr81829.diff
@@ -0,0 +1,308 @@
+From f8029ed6d3dd444ee2608146118f2189cf9ef0d8 Mon Sep 17 00:00:00 2001
+From: marxin <mliska@suse.cz>
+Date: Mon, 14 Aug 2017 13:56:32 +0200
+Subject: [PATCH] Fix file find utils and add unit tests (PR driver/81829).
+
+gcc/ChangeLog:
+
+2017-08-14 Martin Liska <mliska@suse.cz>
+
+ PR driver/81829
+ * file-find.c (do_add_prefix): Always append DIR_SEPARATOR
+ at the end of a prefix.
+ (remove_prefix): Properly remove elements and accept also
+ path without a trailing DIR_SEPARATOR.
+ (purge): New function.
+ (file_find_verify_prefix_creation): Likewise.
+ (file_find_verify_prefix_add): Likewise.
+ (file_find_verify_prefix_removal): Likewise.
+ (file_find_c_tests): Likewise.
+ * selftest-run-tests.c (selftest::run_tests): Add new
+ file_find_c_tests.
+ * selftest.h (file_find_c_tests): Likewise.
+---
+ gcc/file-find.c | 182 ++++++++++++++++++++++++++++++++++++++++++-----
+ gcc/gcc-ar.c | 19 +++--
+ gcc/selftest-run-tests.c | 1 +
+ gcc/selftest.h | 1 +
+ 4 files changed, 179 insertions(+), 24 deletions(-)
+
+Index: b/src/gcc/file-find.c
+===================================================================
+--- a/src/gcc/file-find.c
++++ b/src/gcc/file-find.c
+@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.
+ #include "system.h"
+ #include "filenames.h"
+ #include "file-find.h"
++#include "selftest.h"
+
+ static bool debug = false;
+
+@@ -126,11 +127,22 @@ do_add_prefix (struct path_prefix *ppref
+ /* Keep track of the longest prefix. */
+
+ len = strlen (prefix);
++ bool append_separator = !IS_DIR_SEPARATOR (prefix[len - 1]);
++ if (append_separator)
++ len++;
++
+ if (len > pprefix->max_len)
+ pprefix->max_len = len;
+
+ pl = XNEW (struct prefix_list);
+- pl->prefix = xstrdup (prefix);
++ char *dup = XCNEWVEC (char, len + 1);
++ memcpy (dup, prefix, append_separator ? len - 1 : len);
++ if (append_separator)
++ {
++ dup[len - 1] = DIR_SEPARATOR;
++ dup[len] = '\0';
++ }
++ pl->prefix = dup;
+
+ if (*prev)
+ pl->next = *prev;
+@@ -212,34 +224,170 @@ prefix_from_string (const char *p, struc
+ void
+ remove_prefix (const char *prefix, struct path_prefix *pprefix)
+ {
+- struct prefix_list *remove, **prev, **remove_prev = NULL;
++ char *dup = NULL;
+ int max_len = 0;
++ size_t len = strlen (prefix);
++ if (prefix[len - 1] != DIR_SEPARATOR)
++ {
++ char *dup = XNEWVEC (char, len + 2);
++ memcpy (dup, prefix, len);
++ dup[len] = DIR_SEPARATOR;
++ dup[len + 1] = '\0';
++ prefix = dup;
++ }
+
+ if (pprefix->plist)
+ {
+- prev = &pprefix->plist;
+- for (struct prefix_list *pl = pprefix->plist; pl->next; pl = pl->next)
++ prefix_list *prev = NULL;
++ for (struct prefix_list *pl = pprefix->plist; pl;)
+ {
+ if (strcmp (prefix, pl->prefix) == 0)
+ {
+- remove = pl;
+- remove_prev = prev;
+- continue;
++ if (prev == NULL)
++ pprefix->plist = pl->next;
++ else
++ prev->next = pl->next;
++
++ prefix_list *remove = pl;
++ free (remove);
++ pl = pl->next;
+ }
++ else
++ {
++ prev = pl;
+
+- int l = strlen (pl->prefix);
+- if (l > max_len)
+- max_len = l;
++ int l = strlen (pl->prefix);
++ if (l > max_len)
++ max_len = l;
+
+- prev = &pl;
+- }
+-
+- if (remove_prev)
+- {
+- *remove_prev = remove->next;
+- free (remove);
++ pl = pl->next;
++ }
+ }
+
+ pprefix->max_len = max_len;
+ }
++
++ if (dup)
++ free (dup);
++}
++
++#if CHECKING_P
++
++namespace selftest {
++
++/* Encode '#' and '_' to path and dir separators in order to test portability
++ of the test-cases. */
++
++static char *
++purge (const char *input)
++{
++ char *s = xstrdup (input);
++ for (char *c = s; *c != '\0'; c++)
++ switch (*c)
++ {
++ case '/':
++ case ':':
++ *c = 'a'; /* Poison default string values. */
++ break;
++ case '_':
++ *c = PATH_SEPARATOR;
++ break;
++ case '#':
++ *c = DIR_SEPARATOR;
++ break;
++ default:
++ break;
++ }
++
++ return s;
++}
++
++const char *env1 = purge ("#home#user#bin_#home#user#bin_#bin_#usr#bin");
++const char *env2 = purge ("#root_#root_#root");
++
++/* Verify creation of prefix. */
++
++static void
++file_find_verify_prefix_creation (void)
++{
++ path_prefix prefix;
++ memset (&prefix, 0, sizeof (prefix));
++ prefix_from_string (env1, &prefix);
++
++ ASSERT_EQ (15, prefix.max_len);
++
++ /* All prefixes end with DIR_SEPARATOR. */
++ ASSERT_STREQ (purge ("#home#user#bin#"), prefix.plist->prefix);
++ ASSERT_STREQ (purge ("#home#user#bin#"), prefix.plist->next->prefix);
++ ASSERT_STREQ (purge ("#bin#"), prefix.plist->next->next->prefix);
++ ASSERT_STREQ (purge ("#usr#bin#"), prefix.plist->next->next->next->prefix);
++ ASSERT_EQ (NULL, prefix.plist->next->next->next->next);
++}
++
++/* Verify adding a prefix. */
++
++static void
++file_find_verify_prefix_add (void)
++{
++ path_prefix prefix;
++ memset (&prefix, 0, sizeof (prefix));
++ prefix_from_string (env1, &prefix);
++
++ add_prefix (&prefix, purge ("#root"));
++ ASSERT_STREQ (purge ("#home#user#bin#"), prefix.plist->prefix);
++ ASSERT_STREQ (purge ("#root#"),
++ prefix.plist->next->next->next->next->prefix);
++
++ add_prefix_begin (&prefix, purge ("#var"));
++ ASSERT_STREQ (purge ("#var#"), prefix.plist->prefix);
++}
++
++/* Verify adding a prefix. */
++
++static void
++file_find_verify_prefix_removal (void)
++{
++ path_prefix prefix;
++ memset (&prefix, 0, sizeof (prefix));
++ prefix_from_string (env1, &prefix);
++
++ /* All occurences of a prefix should be removed. */
++ remove_prefix (purge ("#home#user#bin"), &prefix);
++
++ ASSERT_EQ (9, prefix.max_len);
++ ASSERT_STREQ (purge ("#bin#"), prefix.plist->prefix);
++ ASSERT_STREQ (purge ("#usr#bin#"), prefix.plist->next->prefix);
++ ASSERT_EQ (NULL, prefix.plist->next->next);
++
++ remove_prefix (purge ("#usr#bin#"), &prefix);
++ ASSERT_EQ (5, prefix.max_len);
++ ASSERT_STREQ (purge ("#bin#"), prefix.plist->prefix);
++ ASSERT_EQ (NULL, prefix.plist->next);
++
++ remove_prefix (purge ("#dev#random#"), &prefix);
++ remove_prefix (purge ("#bi#"), &prefix);
++
++ remove_prefix (purge ("#bin#"), &prefix);
++ ASSERT_EQ (NULL, prefix.plist);
++ ASSERT_EQ (0, prefix.max_len);
++
++ memset (&prefix, 0, sizeof (prefix));
++ prefix_from_string (env2, &prefix);
++ ASSERT_EQ (6, prefix.max_len);
++
++ remove_prefix (purge ("#root#"), &prefix);
++ ASSERT_EQ (NULL, prefix.plist);
++ ASSERT_EQ (0, prefix.max_len);
+ }
++
++/* Run all of the selftests within this file. */
++
++void file_find_c_tests ()
++{
++ file_find_verify_prefix_creation ();
++ file_find_verify_prefix_add ();
++ file_find_verify_prefix_removal ();
++}
++
++} // namespace selftest
++#endif /* CHECKING_P */
+Index: b/src/gcc/gcc-ar.c
+===================================================================
+--- a/src/gcc/gcc-ar.c
++++ b/src/gcc/gcc-ar.c
+@@ -194,15 +194,20 @@ main (int ac, char **av)
+ #ifdef CROSS_DIRECTORY_STRUCTURE
+ real_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
+ #endif
+- /* Do not search original location in the same folder. */
+- char *exe_folder = lrealpath (av[0]);
+- exe_folder[strlen (exe_folder) - strlen (lbasename (exe_folder))] = '\0';
+- char *location = concat (exe_folder, PERSONALITY, NULL);
++ char *wrapper_file = lrealpath (av[0]);
++ exe_name = lrealpath (find_a_file (&path, real_exe_name, X_OK));
+
+- if (access (location, X_OK) == 0)
+- remove_prefix (exe_folder, &path);
++ /* If the exe_name points to the wrapper, remove folder of the wrapper
++ from prefix and try search again. */
++ if (strcmp (exe_name, wrapper_file) == 0)
++ {
++ char *exe_folder = wrapper_file;
++ exe_folder[strlen (exe_folder) - strlen (lbasename (exe_folder))] = '\0';
++ remove_prefix (exe_folder, &path);
++
++ exe_name = find_a_file (&path, real_exe_name, X_OK);
++ }
+
+- exe_name = find_a_file (&path, real_exe_name, X_OK);
+ if (!exe_name)
+ {
+ fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
+Index: b/src/gcc/selftest-run-tests.c
+===================================================================
+--- a/src/gcc/selftest-run-tests.c
++++ b/src/gcc/selftest-run-tests.c
+@@ -66,6 +66,7 @@ selftest::run_tests ()
+ sreal_c_tests ();
+ fibonacci_heap_c_tests ();
+ typed_splay_tree_c_tests ();
++ file_find_c_tests ();
+
+ /* Mid-level data structures. */
+ input_c_tests ();
+Index: b/src/gcc/selftest.h
+===================================================================
+--- a/src/gcc/selftest.h
++++ b/src/gcc/selftest.h
+@@ -196,6 +196,7 @@ extern void tree_c_tests ();
+ extern void tree_cfg_c_tests ();
+ extern void vec_c_tests ();
+ extern void wide_int_cc_tests ();
++extern void file_find_c_tests ();
+
+ extern int num_passes;
+