From 11a07a7319676b55b9668fdfbf159580388d0318 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 23 Apr 2017 23:01:00 -0700 Subject: [PATCH] nasmlib: add function to splice pathnames Add a function to splice a pathname consisting of a directory and a filename. It is worth noting that this function is limited to that particular use case: in particular, it does NOT currently support concatenating a filename which itself contains directory components to a non-null directory. Combining directory names is extremely system-dependent and probably needs more than just parameterized code in many cases, for example, on VMS combining "foo:[bar]" with "[baz]quux" should produce "foo:[bar.baz]quux" whereas combining "foo:[bar]" and baz:quux" is an outright error. Signed-off-by: H. Peter Anvin --- include/nasmlib.h | 9 ++++++++- nasmlib/path.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/nasmlib.h b/include/nasmlib.h index 0b2bcb17..672764c6 100644 --- a/include/nasmlib.h +++ b/include/nasmlib.h @@ -395,7 +395,14 @@ char *nasm_opt_val(char *p, char **opt, char **val); * * The buffer returned must be freed by the caller */ -char *nasm_realpath(const char *rel_path); +char * safe_alloc nasm_realpath(const char *rel_path); + +/* + * Path-splitting and merging functions + */ +char * safe_alloc nasm_dirname(const char *path); +char * safe_alloc nasm_basename(const char *path); +char * safe_alloc nasm_catfile(const char *dir, const char *path); const char * pure_func prefix_name(int); diff --git a/nasmlib/path.c b/nasmlib/path.c index 855440ea..72136546 100644 --- a/nasmlib/path.c +++ b/nasmlib/path.c @@ -42,17 +42,20 @@ #if defined(unix) || defined(__unix) || defined(__unix__) # define separators "/" # define cleandirend "/" +# define catsep '/' # define leaveonclean 1 # define curdir "." #elif defined(__MSDOS__) || defined(__WINDOWS__) || \ defined(__OS2__) || defined(_WIN16) || defined(_WIN32) # define separators "/\\:" # define cleandirend "/\\" +# define catsep '\\' # define leaveonclean 2 /* Leave \\ at the start alone */ # define curdir "." #elif defined(Macintosh) /* MacOS classic? */ # define separators ":" # define curdir ":" +# define catsep ":" # define cleandirend ":" # define leaveonclean 0 # define leave_leading 1 @@ -68,6 +71,10 @@ # define curdir "" #endif +/* + * This is an inline, because most compilers can greatly simplify this + * for a fixed string, like we have here. + */ static inline bool ismatch(const char *charset, char ch) { const char *p; @@ -129,3 +136,32 @@ char *nasm_dirname(const char *path) return nasm_strndup(path, p-path); } + +/* Concatenate a directory path and a filename */ +char *nasm_catfile(const char *dir, const char *file) +{ +#ifndef catsep + return nasm_strcat(dir, file); +#else + size_t dl = strlen(dir); + size_t fl = strlen(file); + char *p; + bool dosep = true; + + if (!dl || ismatch(separators, dir[dl-1])) { + /* No separator necessary */ + dosep = false; + } + + p = nasm_malloc(dl + fl + dosep + 1); + + memcpy(p, dir, dl); + p += dl; + if (dosep) + *p++ = catsep; + + memcpy(p, file, fl+1); + + return p; +#endif +} -- 2.11.4.GIT