diff options
author | H. Peter Anvin <hpa@zytor.com> | 2017-04-23 23:01:00 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2017-04-23 23:01:00 -0700 |
commit | 11a07a7319676b55b9668fdfbf159580388d0318 (patch) | |
tree | 39ea5ada420ba741c1462ced4c53a7662546f27b | |
parent | 0979957e19930407a3b202600aa99ec1fe0bd740 (diff) | |
download | nasm-11a07a7319676b55b9668fdfbf159580388d0318.tar.gz |
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 <hpa@zytor.com>
-rw-r--r-- | include/nasmlib.h | 9 | ||||
-rw-r--r-- | nasmlib/path.c | 36 |
2 files changed, 44 insertions, 1 deletions
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 +} |