Add libiberty/concat styled concat_path function

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.
This commit is contained in:
Philipp Rudo
2017-03-16 10:50:23 +01:00
committed by Andreas Arnez
parent ad0b0e50cd
commit 09e978d277
3 changed files with 74 additions and 0 deletions

View File

@@ -83,6 +83,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

View File

@@ -3181,6 +3181,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 (std::initializer_list<std::string> args,
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 (std::initializer_list<std::string> args,
std::string dir_separator)
{
std::string dst;
dst.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 (dst.c_str (), dir_separator.c_str ()))
dst.erase (dst.length () - dir_separator.length (),
dir_separator.length ());
else if (!dst.empty ()
&& !startswith (arg.c_str (), dir_separator.c_str ())
&& !endswith (dst.c_str (), dir_separator.c_str ())
&& dst != TARGET_SYSROOT_PREFIX)
dst += dir_separator;
dst += arg;
}
dst.shrink_to_fit ();
return dst;
}
#ifdef HAVE_WAITPID
#ifdef SIGALRM

View File

@@ -24,6 +24,7 @@
#include "exceptions.h"
#include "common/scoped_restore.h"
#include <chrono>
#include <string>
extern void initialize_utils (void);
@@ -140,6 +141,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 (std::initializer_list<std::string> args,
std::string dir_separator);
#define concat_path(...) _concat_path ({__VA_ARGS__}, SLASH_STRING)
char *ldirname (const char *filename);
extern int count_path_elements (const char *path);