This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC PATCH 2/6] Add libiberty/concat styled concat_path function
- From: Omair Javaid <omair dot javaid at linaro dot org>
- To: gdb-patches at sourceware dot org
- Cc: palves at redhat dot com, prudo at linux dot ibm dot com, arnez at linux dot vnet dot ibm dot com, peter dot griffin at linaro dot org, Ulrich dot Weigand at de dot ibm dot com, kieran at linuxembedded dot co dot uk
- Date: Tue, 29 Jan 2019 10:03:15 +0500
- Subject: [RFC PATCH 2/6] Add libiberty/concat styled concat_path function
- References: <1548738199-9403-1-git-send-email-omair.javaid@linaro.org>
From: Philipp Rudo <prudo@linux.ibm.com>
This commit adds concat_path function to concatenate an arbitrary number of
path elements. The function automatically adds an directory separator between
two elements as needed.
gdb/ChangeLog:
* common/common-utils.h (endswith): New function.
* utils.c (_concat_path, approx_path_length): New function.
* utils.h (_concat_path): New export.
(concat_path): New define.
---
gdb/common/common-utils.h | 11 +++++++++++
gdb/utils.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
gdb/utils.h | 16 ++++++++++++++++
3 files changed, 73 insertions(+)
diff --git a/gdb/common/common-utils.h b/gdb/common/common-utils.h
index b2cb516..bb7c5b1 100644
--- a/gdb/common/common-utils.h
+++ b/gdb/common/common-utils.h
@@ -109,6 +109,17 @@ startswith (const char *string, const char *pattern)
return strncmp (string, pattern, strlen (pattern)) == 0;
}
+/* Return non-zero if the end of STRING matches PATTERN, zero
+ otherwise. */
+
+static inline int
+endswith (const char *string, const char *pattern)
+{
+ return (strlen (string) > strlen (pattern)
+ && strncmp (string + strlen (string) - strlen (pattern), pattern,
+ strlen (pattern)) == 0);
+}
+
ULONGEST strtoulst (const char *num, const char **trailer, int base);
/* Skip leading whitespace characters in INP, returning an updated
diff --git a/gdb/utils.c b/gdb/utils.c
index 2394443..8c8e152 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -3077,6 +3077,52 @@ substitute_path_component (std::string &str, const std::string &from,
}
}
+/* Approximate length of final path. Helper for concat_path. */
+
+static inline unsigned long
+approx_path_length (const std::initializer_list<const std::string> args,
+ const std::string &dir_separator)
+{
+ size_t length = 0;
+
+ for (const std::string &arg: args)
+ length += arg.length () + dir_separator.length ();
+
+ return length;
+}
+
+/* See utils.h. */
+
+std::string
+_concat_path (const std::initializer_list<const std::string> args,
+ const std::string &dir_separator)
+{
+ std::string ret;
+ ret.reserve (approx_path_length (args, dir_separator));
+
+ for (const std::string &arg : args)
+ {
+ if (arg.empty ())
+ continue;
+
+ if (startswith (arg.c_str (), dir_separator.c_str ())
+ && endswith (ret.c_str (), dir_separator.c_str ()))
+ ret.erase (ret.length () - dir_separator.length (),
+ dir_separator.length ());
+
+ else if (!ret.empty ()
+ && !startswith (arg.c_str (), dir_separator.c_str ())
+ && !endswith (ret.c_str (), dir_separator.c_str ())
+ && ret != TARGET_SYSROOT_PREFIX)
+ ret += dir_separator;
+
+ ret += arg;
+ }
+
+ ret.shrink_to_fit ();
+ return ret;
+}
+
#ifdef HAVE_WAITPID
#ifdef SIGALRM
diff --git a/gdb/utils.h b/gdb/utils.h
index bc319de..f8178f8 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -301,6 +301,22 @@ extern void substitute_path_component (std::string &str,
const std::string &from,
const std::string &to);
+/* Concatenate an arbitrary number of path elements. Adds and removes
+ directory separators as needed.
+
+ concat_path (/first, second) => /first/second
+ concat_path (first, second) => first/second
+ concat_path (first/, second) => first/second
+ concat_path (first, /second) => first/second
+ concat_path (first/, /second) => first/second
+ concat_path (target:, second) => target:second
+ */
+
+extern std::string _concat_path (const std::initializer_list<const std::string> args,
+ const std::string &dir_separator);
+
+#define concat_path(...) _concat_path ({__VA_ARGS__}, SLASH_STRING)
+
std::string ldirname (const char *filename);
extern int count_path_elements (const char *path);
--
2.7.4