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>
This commit is contained in:
H. Peter Anvin 2017-04-23 23:01:00 -07:00
parent 0979957e19
commit 11a07a7319
2 changed files with 44 additions and 1 deletions

View File

@ -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);

View File

@ -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
}