lavu/avstring: add av_append_path_component() funcion
authorLukasz Marek <lukasz.m.luki2@gmail.com>
Sat, 5 Jul 2014 16:12:02 +0000 (18:12 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 31 Mar 2015 21:50:46 +0000 (23:50 +0200)
Convinient function to build paths.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
doc/APIchanges
libavutil/avstring.c
libavutil/avstring.h
libavutil/version.h
tests/ref/fate/avstring

index f8dcc99..b1beb9d 100644 (file)
@@ -15,6 +15,9 @@ libavutil:     2014-08-09
 
 API changes, most recent first:
 
+2015-xx-xx - xxxxxxx - lavu 54.22.100 - avstring.h
+  Add av_append_path_component()
+
 2015-03-27 - 184084c - lavf 56.27.100 - avio.h url.h
   New directory listing API.
 
index 25c65b4..670801e 100644 (file)
@@ -269,6 +269,37 @@ const char *av_dirname(char *path)
     return path;
 }
 
+char *av_append_path_component(const char *path, const char *component)
+{
+    size_t p_len, c_len;
+    char *fullpath;
+
+    if (!path)
+        return av_strdup(component);
+    if (!component)
+        return av_strdup(path);
+
+    p_len = strlen(path);
+    c_len = strlen(component);
+    if (p_len > SIZE_MAX - c_len || p_len + c_len > SIZE_MAX - 2)
+        return NULL;
+    fullpath = av_malloc(p_len + c_len + 2);
+    if (fullpath) {
+        if (p_len) {
+            av_strlcpy(fullpath, path, p_len + 1);
+            if (c_len) {
+                if (fullpath[p_len - 1] != '/' && component[0] != '/')
+                    fullpath[p_len++] = '/';
+                else if (fullpath[p_len - 1] == '/' && component[0] == '/')
+                    p_len--;
+            }
+        }
+        av_strlcpy(&fullpath[p_len], component, c_len + 1);
+        fullpath[p_len + c_len] = 0;
+    }
+    return fullpath;
+}
+
 int av_escape(char **dst, const char *src, const char *special_chars,
               enum AVEscapeMode mode, int flags)
 {
@@ -427,6 +458,7 @@ int av_match_list(const char *name, const char *list, char separator)
 int main(void)
 {
     int i;
+    char *fullpath;
     static const char * const strings[] = {
         "''",
         "",
@@ -467,6 +499,19 @@ int main(void)
         av_free(q);
     }
 
+    printf("Testing av_append_path_component()\n");
+    #define TEST_APPEND_PATH_COMPONENT(path, component, expected) \
+        fullpath = av_append_path_component((path), (component)); \
+        printf("%s = %s\n", fullpath, expected); \
+        av_free(fullpath);
+    TEST_APPEND_PATH_COMPONENT(NULL, NULL, "(null)")
+    TEST_APPEND_PATH_COMPONENT("path", NULL, "path");
+    TEST_APPEND_PATH_COMPONENT(NULL, "comp", "comp");
+    TEST_APPEND_PATH_COMPONENT("path", "comp", "path/comp");
+    TEST_APPEND_PATH_COMPONENT("path/", "comp", "path/comp");
+    TEST_APPEND_PATH_COMPONENT("path", "/comp", "path/comp");
+    TEST_APPEND_PATH_COMPONENT("path/", "/comp", "path/comp");
+    TEST_APPEND_PATH_COMPONENT("path/path2/", "/comp/comp2", "path/path2/comp/comp2");
     return 0;
 }
 
index ffb7aa6..466edaf 100644 (file)
@@ -276,6 +276,16 @@ const char *av_dirname(char *path);
  */
 int av_match_name(const char *name, const char *names);
 
+/**
+ * Append path component to the existing path.
+ * Path separator '/' is placed between when needed.
+ * Resulting string have to be freed with av_free().
+ * @param path      base path
+ * @param component component to be appended
+ * @return new path or NULL on error.
+ */
+char *av_append_path_component(const char *path, const char *component);
+
 enum AVEscapeMode {
     AV_ESCAPE_MODE_AUTO,      ///< Use auto-selected escaping mode.
     AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping.
index 4d710dd..30be0f0 100644 (file)
@@ -56,7 +56,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  54
-#define LIBAVUTIL_VERSION_MINOR  21
+#define LIBAVUTIL_VERSION_MINOR  22
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
index bc231e8..1ca9be5 100644 (file)
@@ -25,3 +25,12 @@ Testing av_get_token()
 |'foo : \ \  '   : blahblah| -> |foo : \ \  | + |: blahblah|
 |'\fo\o:': blahblah| -> |\fo\o:| + |: blahblah|
 |\'fo\o\:':  foo  '  :blahblah| -> |'foo::  foo  | + |:blahblah|
+Testing av_append_path_component()
+(null) = (null)
+path = path
+comp = comp
+path/comp = path/comp
+path/comp = path/comp
+path/comp = path/comp
+path/comp = path/comp
+path/path2/comp/comp2 = path/path2/comp/comp2