summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2017-04-23 23:01:00 -0700
committerH. Peter Anvin <hpa@zytor.com>2017-04-23 23:01:00 -0700
commit11a07a7319676b55b9668fdfbf159580388d0318 (patch)
tree39ea5ada420ba741c1462ced4c53a7662546f27b
parent0979957e19930407a3b202600aa99ec1fe0bd740 (diff)
downloadnasm-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.h9
-rw-r--r--nasmlib/path.c36
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
+}