eina_vpath: introduce eina_vpath in style of snprintf

Summary:
this can be usefull for later regactor usages.

Depends on D6742

Reviewers: zmike, stefan_schmidt, #committers

Reviewed By: zmike, #committers

Subscribers: #reviewers, segfaultxavi, cedric, #committers, zmike

Tags: PHID-PROJ-55rnlag4d454jfmlmuhu

Differential Revision: https://phab.enlightenment.org/D6743
This commit is contained in:
Marcel Hollerbach 2018-08-20 12:56:51 -04:00 committed by Mike Blumenkrantz
parent aa416afffb
commit e31ce7b287
3 changed files with 73 additions and 14 deletions

View File

@ -214,6 +214,19 @@ _fetch_user_homedir(char **str, const char *name, const char *error)
EAPI char *
eina_vpath_resolve(const char* path)
{
char buf[PATH_MAX];
if (eina_vpath_resolve_snprintf(buf, sizeof(buf), path) > 0)
return strdup(buf);
return NULL;
}
EAPI int
eina_vpath_resolve_snprintf(char *str, size_t size, const char *format, ...)
{
va_list args;
char *path;
int len;
// XXX: implement parse of path then look up in hash if not just create
// object where path and result are the same and return that with
// path set and result set to resolved path - return obj handler calls
@ -223,7 +236,11 @@ eina_vpath_resolve(const char* path)
/* FIXME: not working for WIndows */
// /* <- full path
if (!path) return NULL;
path = alloca(size + 1);
va_start(args, format);
len = vsnprintf(path, size, format, args);
va_end(args);
if (path[0] == '~')
{
@ -237,7 +254,7 @@ eina_vpath_resolve(const char* path)
// ~username/ <- homedir of user "username"
else
{
char *p, *name, buf[PATH_MAX];
char *p, *name;
for (p = path + 1; *p; p++)
{
@ -248,21 +265,19 @@ eina_vpath_resolve(const char* path)
name[p - path - 1] = 0;
if (!_fetch_user_homedir(&home, name, path))
return NULL;
return 0;
path = p;
}
if (home)
{
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "%s%s", home, path);
return strdup(buf);
return snprintf(str, size, "%s%s", home, path);
}
}
// (:xxx:)/* ... <- meta hash table
else if ((path[0] == '(') && (path[1] == ':'))
{
const char *p, *end, *meta;
char *name, buf[PATH_MAX];
char *name;
int max_len = strlen(path);
Eina_Bool found = EINA_FALSE;
@ -280,13 +295,13 @@ eina_vpath_resolve(const char* path)
if (!found)
{
ERR("(: Needs to have a matching ':)'\nThe string was: %s", path);
return NULL;
return 0;
}
if (*p != '/')
{
ERR("A / is expected after :)\nThe string was: %s", path);
return NULL;
return 0;
}
if (found)
@ -297,25 +312,24 @@ eina_vpath_resolve(const char* path)
meta = _eina_vpath_data_get(name);
if (meta)
{
snprintf(buf, sizeof(buf), "%s%s", meta, end + 2);
return strdup(buf);
return snprintf(str, size, "%s%s", meta, end + 2);
}
else
{
ERR("Meta key '%s' was not registered!\nThe string was: %s", name, path);
return NULL;
return 0;
}
}
}
//just return the path, since we assume that this is a normal path
else
{
return strdup(path);
return snprintf(str, size, "%s", path);
}
ERR("The path has to start with either '~/' or '(:NAME:)/' or be a normal path \nThe string was: %s", path);
return NULL;
return 0;
}
EAPI void

View File

@ -94,5 +94,19 @@ typedef const char * Eina_Vpath;
*/
EAPI char *eina_vpath_resolve(Eina_Vpath path);
/*
* Translate a virtual path into a normal path, and print it into str.
*
* @param str the buffer to stuff the characters into
* @param size the size of the buffer
* @param format A snprintf style format string, which will get evalulated after the vpath strings are getting replaced
* @param ... The arguments for the format string
*
* @return the number of characters that are written into str, on a error a value < 0 is returned.
*
* @since 1.21
*
*/
EAPI int eina_vpath_resolve_snprintf(char *str, size_t size, const char *format, ...);
#endif
#endif

View File

@ -5,6 +5,7 @@
#include <Eina.h>
#include <check.h>
#include "eina_suite.h"
#include <pwd.h>
EFL_START_TEST(eina_test_vpath_valid)
{
@ -20,6 +21,7 @@ EFL_START_TEST(eina_test_vpath_valid)
snprintf(test, sizeof(test), "%s/bla", eina_environment_home_get());
ck_assert_str_eq(eina_vpath_resolve("(:home:)/bla"), test);
ck_assert_str_eq(eina_vpath_resolve("/test/for/the/last/case"), "/test/for/the/last/case");
}
EFL_END_TEST
@ -31,7 +33,34 @@ EFL_START_TEST(eina_test_vpath_invalid)
ck_assert_ptr_eq(eina_vpath_resolve("(:"), NULL);
ck_assert_ptr_eq(eina_vpath_resolve("(:home:)"), NULL);
ck_assert_ptr_eq(eina_vpath_resolve("(:wrong_meta_key:)/"), NULL);
}
EFL_END_TEST
EFL_START_TEST(eina_test_vpath_snprintf)
{
char *string = "blablabla";
int x = 1337;
char buf[PATH_MAX];
char cmp[PATH_MAX];
eina_vpath_resolve_snprintf(buf, sizeof(buf), "(:home:)/%s/%d/", string, x);
snprintf(cmp, sizeof(cmp), "%s/%s/%d/", eina_environment_home_get(), string, x);
ck_assert_str_eq(buf, cmp);
}
EFL_END_TEST
EFL_START_TEST(eina_test_vpath_user)
{
char buf[PATH_MAX];
char cmp[PATH_MAX];
struct passwd *pwent;
pwent = getpwuid(getuid());
eina_vpath_resolve_snprintf(buf, sizeof(buf), "~%s/foo/bar/king/kong/", pwent->pw_name);
snprintf(cmp, sizeof(cmp), "%s/foo/bar/king/kong/", pwent->pw_dir);
ck_assert_str_eq(buf, cmp);
}
EFL_END_TEST
@ -39,4 +68,6 @@ void eina_test_vpath(TCase *tc)
{
tcase_add_test(tc, eina_test_vpath_invalid);
tcase_add_test(tc, eina_test_vpath_valid);
tcase_add_test(tc, eina_test_vpath_snprintf);
tcase_add_test(tc, eina_test_vpath_user);
}