lavu/avstring: add av_append_path_component() funcion

Convinient function to build paths.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Lukasz Marek 2014-07-05 18:12:02 +02:00 committed by Michael Niedermayer
parent 8b76c0eb56
commit 31886968d3
5 changed files with 68 additions and 1 deletions

View 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.

View 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;
}

View 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.

View 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, \

View 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