diff options
author | João Antônio Cardoso <joao.maker@gmail.com> | 2020-07-28 17:26:46 -0300 |
---|---|---|
committer | Felipe Magno de Almeida <felipe@expertise.dev> | 2020-12-14 13:41:04 -0300 |
commit | abcb324c2dedb1107f0fd0298f9a8bb41d6d76d2 (patch) | |
tree | 097108a9336f2c95e2e42373cd911f474be4388a | |
parent | 7c74fc9b5fe14ae6f9abb3efc8889a815312230e (diff) | |
download | efl-abcb324c2dedb1107f0fd0298f9a8bb41d6d76d2.tar.gz |
evil: Reimplement basename for windows considering possible reentrancy
Use thread local storage (TLS) to enable the usage with multiples threads
-rw-r--r-- | src/lib/evil/evil_libgen.c | 44 | ||||
-rw-r--r-- | src/lib/evil/evil_libgen.h | 21 | ||||
-rw-r--r-- | src/lib/evil/meson.build | 1 | ||||
-rw-r--r-- | src/tests/evil/evil_test_libgen.c | 191 |
4 files changed, 257 insertions, 0 deletions
diff --git a/src/lib/evil/evil_libgen.c b/src/lib/evil/evil_libgen.c new file mode 100644 index 0000000000..6ae58def47 --- /dev/null +++ b/src/lib/evil/evil_libgen.c @@ -0,0 +1,44 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <evil_private.h> + +#include <stdlib.h> +#include <string.h> /* strlen */ + +EVIL_API char * +evil_basename(char *path) +{ + // Expected from posix + if ((path == NULL) || (*path == '\0') ) return "."; + + // Remove trailing '\\' + unsigned int len = strlen(path); + if ((len > 1) && ((path[len -1] == '/') || (path[len -1] == '\\'))) + path[len -1] = '\0'; + + // Search for the last slash + while(--len) + if ((path[len] == '/') || (path[len] == '\\')) + break; + + if(!len) return path; + else return &path[len +1]; +} + +EVIL_API char * +evil_dirname(char *path) +{ + // Expected from posix + if ((path == NULL) || (*path == '\0') ) return "."; + + // Search for the last slash ignoring trailing '\\' + unsigned int len = strlen(path); + while(--len) + if ((path[len] == '/') || (path[len] == '\\')) + break; + path[len] = '\0'; + + return path; +} diff --git a/src/lib/evil/evil_libgen.h b/src/lib/evil/evil_libgen.h new file mode 100644 index 0000000000..0c0928da7e --- /dev/null +++ b/src/lib/evil/evil_libgen.h @@ -0,0 +1,21 @@ +#ifndef __EVIL_LIBGEN_H__ +#define __EVIL_LIBGEN_H__ + +#include <evil_private.h> + +#ifndef HAVE_BASENAME +# define HAVE_BASENAME +# define basename evil_basename +#endif + +#ifndef HAVE_DIRNAME +# define HAVE_DIRNAME +# define dirname evil_dirname +#endif + +EVIL_API char* evil_basename (char* path); + +EVIL_API char* evil_dirname (char* path); + +#endif + diff --git a/src/lib/evil/meson.build b/src/lib/evil/meson.build index dc86e6af0b..3a2c0d5dd4 100644 --- a/src/lib/evil/meson.build +++ b/src/lib/evil/meson.build @@ -18,6 +18,7 @@ if target_machine.system() == 'windows' 'evil_unistd.c', 'evil_util.c', 'evil_private.h', + 'evil_libgen.c', ]) psapi = cc.find_library('psapi') diff --git a/src/tests/evil/evil_test_libgen.c b/src/tests/evil/evil_test_libgen.c new file mode 100644 index 0000000000..80ba19512a --- /dev/null +++ b/src/tests/evil/evil_test_libgen.c @@ -0,0 +1,191 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include <evil_private.h> + +#include "evil_suite.h" + +EFL_START_TEST(evil_libgen_basename_simple) +{ + char path[] = "/bin/foo/bar.h"; + char expected[] = "bar.h"; + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_short) +{ + char path[] = "a"; + char expected[] = "a"; + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_root) +{ + char path[] = "/"; + char expected[] = "/"; + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_trailing) +{ + char path[] = "/bin/foo/"; + char expected[] = "foo"; + + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_empty) +{ + char path[] = ""; + char expected[] = "."; + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_null) +{ + char expected[] = "."; + char *res = evil_basename(NULL); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_filename) +{ + char path[] = "bar.h"; + char expected[] = "bar.h"; + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_basename_windows) +{ + char path[] = "C:\\foo\\bar.h"; + char expected[] = "bar.h"; + char *res = evil_basename(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_simple) +{ + char path[] = "/bin/foo/bar.h"; + char expected[] = "/bin/foo"; + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_short) +{ + char path[] = "a"; + char expected[] = ""; + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_root) +{ + char path[] = "/"; + char expected[] = ""; + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_trailing) +{ + char path[] = "/bin/foo/"; + char expected[] = "/bin/foo"; + + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_empty) +{ + char path[] = ""; + char expected[] = "."; + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_null) +{ + char expected[] = "."; + char *res = evil_dirname(NULL); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_filename) +{ + char path[] = "bar.h"; + char expected[] = ""; + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +EFL_START_TEST(evil_libgen_dirname_windows) +{ + char path[] = "C:\\foo\\bar.h"; + char expected[] = "C:\\foo"; + char *res = evil_dirname(path); + + fail_if(strcmp(res, expected) != 0); +} +EFL_END_TEST + +void evil_test_libgen(TCase *tc) +{ + tcase_add_test(tc, evil_libgen_basename_simple); + tcase_add_test(tc, evil_libgen_basename_short); + tcase_add_test(tc, evil_libgen_basename_root); + tcase_add_test(tc, evil_libgen_basename_trailing); + tcase_add_test(tc, evil_libgen_basename_empty); + tcase_add_test(tc, evil_libgen_basename_null); + tcase_add_test(tc, evil_libgen_basename_filename); + tcase_add_test(tc, evil_libgen_basename_windows); + + tcase_add_test(tc, evil_libgen_dirname_simple); + tcase_add_test(tc, evil_libgen_dirname_short); + tcase_add_test(tc, evil_libgen_dirname_root); + tcase_add_test(tc, evil_libgen_dirname_trailing); + tcase_add_test(tc, evil_libgen_dirname_empty); + tcase_add_test(tc, evil_libgen_dirname_null); + tcase_add_test(tc, evil_libgen_dirname_filename); + tcase_add_test(tc, evil_libgen_dirname_windows); +} |