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 * EAPI char *
eina_vpath_resolve(const char* path) 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 // 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 // object where path and result are the same and return that with
// path set and result set to resolved path - return obj handler calls // 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 */ /* FIXME: not working for WIndows */
// /* <- full path // /* <- 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] == '~') if (path[0] == '~')
{ {
@ -237,7 +254,7 @@ eina_vpath_resolve(const char* path)
// ~username/ <- homedir of user "username" // ~username/ <- homedir of user "username"
else else
{ {
char *p, *name, buf[PATH_MAX]; char *p, *name;
for (p = path + 1; *p; p++) for (p = path + 1; *p; p++)
{ {
@ -248,21 +265,19 @@ eina_vpath_resolve(const char* path)
name[p - path - 1] = 0; name[p - path - 1] = 0;
if (!_fetch_user_homedir(&home, name, path)) if (!_fetch_user_homedir(&home, name, path))
return NULL; return 0;
path = p; path = p;
} }
if (home) if (home)
{ {
char buf[PATH_MAX]; return snprintf(str, size, "%s%s", home, path);
snprintf(buf, sizeof(buf), "%s%s", home, path);
return strdup(buf);
} }
} }
// (:xxx:)/* ... <- meta hash table // (:xxx:)/* ... <- meta hash table
else if ((path[0] == '(') && (path[1] == ':')) else if ((path[0] == '(') && (path[1] == ':'))
{ {
const char *p, *end, *meta; const char *p, *end, *meta;
char *name, buf[PATH_MAX]; char *name;
int max_len = strlen(path); int max_len = strlen(path);
Eina_Bool found = EINA_FALSE; Eina_Bool found = EINA_FALSE;
@ -280,13 +295,13 @@ eina_vpath_resolve(const char* path)
if (!found) if (!found)
{ {
ERR("(: Needs to have a matching ':)'\nThe string was: %s", path); ERR("(: Needs to have a matching ':)'\nThe string was: %s", path);
return NULL; return 0;
} }
if (*p != '/') if (*p != '/')
{ {
ERR("A / is expected after :)\nThe string was: %s", path); ERR("A / is expected after :)\nThe string was: %s", path);
return NULL; return 0;
} }
if (found) if (found)
@ -297,25 +312,24 @@ eina_vpath_resolve(const char* path)
meta = _eina_vpath_data_get(name); meta = _eina_vpath_data_get(name);
if (meta) if (meta)
{ {
snprintf(buf, sizeof(buf), "%s%s", meta, end + 2); return snprintf(str, size, "%s%s", meta, end + 2);
return strdup(buf);
} }
else else
{ {
ERR("Meta key '%s' was not registered!\nThe string was: %s", name, path); 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 //just return the path, since we assume that this is a normal path
else 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); 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 EAPI void

View File

@ -94,5 +94,19 @@ typedef const char * Eina_Vpath;
*/ */
EAPI char *eina_vpath_resolve(Eina_Vpath path); 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
#endif #endif

View File

@ -5,6 +5,7 @@
#include <Eina.h> #include <Eina.h>
#include <check.h> #include <check.h>
#include "eina_suite.h" #include "eina_suite.h"
#include <pwd.h>
EFL_START_TEST(eina_test_vpath_valid) 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()); 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("(:home:)/bla"), test);
ck_assert_str_eq(eina_vpath_resolve("/test/for/the/last/case"), "/test/for/the/last/case");
} }
EFL_END_TEST 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("(:"), NULL);
ck_assert_ptr_eq(eina_vpath_resolve("(:home:)"), NULL); ck_assert_ptr_eq(eina_vpath_resolve("(:home:)"), NULL);
ck_assert_ptr_eq(eina_vpath_resolve("(:wrong_meta_key:)/"), 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 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_invalid);
tcase_add_test(tc, eina_test_vpath_valid); tcase_add_test(tc, eina_test_vpath_valid);
tcase_add_test(tc, eina_test_vpath_snprintf);
tcase_add_test(tc, eina_test_vpath_user);
} }