foxygit / doom Log in
commit ae8c1ed2e0eb1a9292692caf0b5af82217228b3d
Author:     Simon Howard <fraggle@soulsphere.org>
AuthorDate: Sun Sep 9 18:36:47 2018 -0400
Commit:     Simon Howard <fraggle@soulsphere.org>
CommitDate: Sun Sep 9 18:36:47 2018 -0400

    misc: Add M_{Dir,Base}Name utility functions.

    These extract the directory / base filename, equivalent to the Unix
    `dirname` / `basename` commands. Repeated code throughout the codebase
    seems to reimplement this particular functionality.
---
 src/m_misc.c | 39 +++++++++++++++++++++++++++++++++++++++
 src/m_misc.h |  2 ++
 2 files changed, 41 insertions(+)

diff --git a/src/m_misc.c b/src/m_misc.c
index 847cc390..a9f615cf 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -265,6 +265,45 @@ boolean M_StrToInt(const char *str, int *result)
         || sscanf(str, " %d", result) == 1;
 }

+// Returns the directory portion of the given path, without the trailing
+// slash separator character. If no directory is described in the path,
+// the string "." is returned. In either case, the result is newly allocated
+// and must be freed by the caller after use.
+char *M_DirName(const char *path)
+{
+    char *p, *result;
+
+    p = strrchr(path, DIR_SEPARATOR);
+    if (p == NULL)
+    {
+        return M_StringDuplicate(".");
+    }
+    else
+    {
+        result = M_StringDuplicate(path);
+        result[p - path] = '\0';
+        return result;
+    }
+}
+
+// Returns the base filename described by the given path (without the
+// directory name). The result points inside path and nothing new is
+// allocated.
+const char *M_BaseName(const char *path)
+{
+    char *p;
+
+    p = strrchr(path, DIR_SEPARATOR);
+    if (p == NULL)
+    {
+        return path;
+    }
+    else
+    {
+        return p + 1;
+    }
+}
+
 void M_ExtractFileBase(const char *path, char *dest)
 {
     const char *src;
diff --git a/src/m_misc.h b/src/m_misc.h
index 067995e1..81b767fe 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -33,6 +33,8 @@ boolean M_FileExists(const char *file);
 char *M_FileCaseExists(const char *file);
 long M_FileLength(FILE *handle);
 boolean M_StrToInt(const char *str, int *result);
+char *M_DirName(const char *path);
+const char *M_BaseName(const char *path);
 void M_ExtractFileBase(const char *path, char *dest);
 void M_ForceUppercase(char *text);
 void M_ForceLowercase(char *text);