From e1aff6f9f7103ee59e2501d3e6c705a685b20aeb Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 9 Nov 2010 14:38:28 -0800 Subject: [PATCH] util: New function base_name(). --- lib/util.c | 40 ++++++++++++++++----- lib/util.h | 1 + tests/.gitignore | 2 +- tests/automake.mk | 12 +++---- tests/dir_name.at | 25 ------------- tests/file_name.at | 26 ++++++++++++++ tests/{test-dir_name.c => test-file_name.c} | 10 ++++-- tests/testsuite.at | 2 +- 8 files changed, 75 insertions(+), 43 deletions(-) delete mode 100644 tests/dir_name.at create mode 100644 tests/file_name.at rename tests/{test-dir_name.c => test-file_name.c} (80%) diff --git a/lib/util.c b/lib/util.c index 328cfac4..12403cbb 100644 --- a/lib/util.c +++ b/lib/util.c @@ -395,6 +395,14 @@ get_cwd(void) } } +static char * +all_slashes_name(const char *s) +{ + return xstrdup(s[0] == '/' && s[1] == '/' && s[2] != '/' ? "//" + : s[0] == '/' ? "/" + : "."); +} + /* Returns the directory name portion of 'file_name' as a malloc()'d string, * similar to the POSIX dirname() function but thread-safe. */ char * @@ -410,15 +418,31 @@ dir_name(const char *file_name) while (len > 0 && file_name[len - 1] == '/') { len--; } - if (!len) { - return xstrdup((file_name[0] == '/' - && file_name[1] == '/' - && file_name[2] != '/') ? "//" - : file_name[0] == '/' ? "/" - : "."); - } else { - return xmemdup0(file_name, len); + return len ? xmemdup0(file_name, len) : all_slashes_name(file_name); +} + +/* Returns the file name portion of 'file_name' as a malloc()'d string, + * similar to the POSIX basename() function but thread-safe. */ +char * +base_name(const char *file_name) +{ + size_t end, start; + + end = strlen(file_name); + while (end > 0 && file_name[end - 1] == '/') { + end--; + } + + if (!end) { + return all_slashes_name(file_name); } + + start = end; + while (start > 0 && file_name[start - 1] != '/') { + start--; + } + + return xmemdup0(file_name + start, end - start); } /* If 'file_name' starts with '/', returns a copy of 'file_name'. Otherwise, diff --git a/lib/util.h b/lib/util.h index 5147ffc5..6bc17404 100644 --- a/lib/util.h +++ b/lib/util.h @@ -135,6 +135,7 @@ int hexit_value(int c); char *get_cwd(void); char *dir_name(const char *file_name); +char *base_name(const char *file_name); char *abs_file_name(const char *dir, const char *file_name); void ignore(bool x OVS_UNUSED); diff --git a/tests/.gitignore b/tests/.gitignore index f79aff2b..91fa1766 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -9,7 +9,7 @@ /test-classifier /test-csum /test-dhcp-client -/test-dir_name +/test-file_name /test-flows /test-hash /test-hmap diff --git a/tests/automake.mk b/tests/automake.mk index f9c0de0e..9e1bd9c2 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -14,7 +14,7 @@ TESTSUITE_AT = \ tests/daemon-py.at \ tests/ovs-ofctl.at \ tests/vconn.at \ - tests/dir_name.at \ + tests/file_name.at \ tests/aes128.at \ tests/uuid.at \ tests/json.at \ @@ -65,7 +65,7 @@ lcov_wrappers = \ tests/lcov/test-classifier \ tests/lcov/test-csum \ tests/lcov/test-dhcp-client \ - tests/lcov/test-dir_name \ + tests/lcov/test-file_name \ tests/lcov/test-flows \ tests/lcov/test-hash \ tests/lcov/test-hmap \ @@ -114,7 +114,7 @@ valgrind_wrappers = \ tests/valgrind/test-classifier \ tests/valgrind/test-csum \ tests/valgrind/test-dhcp-client \ - tests/valgrind/test-dir_name \ + tests/valgrind/test-file_name \ tests/valgrind/test-flows \ tests/valgrind/test-hash \ tests/valgrind/test-hmap \ @@ -181,9 +181,9 @@ noinst_PROGRAMS += tests/test-csum tests_test_csum_SOURCES = tests/test-csum.c tests_test_csum_LDADD = lib/libopenvswitch.a -noinst_PROGRAMS += tests/test-dir_name -tests_test_dir_name_SOURCES = tests/test-dir_name.c -tests_test_dir_name_LDADD = lib/libopenvswitch.a +noinst_PROGRAMS += tests/test-file_name +tests_test_file_name_SOURCES = tests/test-file_name.c +tests_test_file_name_LDADD = lib/libopenvswitch.a noinst_PROGRAMS += tests/test-flows tests_test_flows_SOURCES = tests/test-flows.c diff --git a/tests/dir_name.at b/tests/dir_name.at deleted file mode 100644 index 062e422a..00000000 --- a/tests/dir_name.at +++ /dev/null @@ -1,25 +0,0 @@ -AT_BANNER([test dir_name function]) - -m4_define([CHECK_DIR_NAME], - [AT_SETUP([dir_name("$1") returns "$2"]) - AT_KEYWORDS([dir_name]) - AT_CHECK([test-dir_name "AS_ESCAPE($1)"], [0], [$2 -]) - AT_CLEANUP]) - -# These are the test cases given in POSIX for dirname(). -CHECK_DIR_NAME([/usr/lib], [/usr]) -CHECK_DIR_NAME([/usr/], [/]) -CHECK_DIR_NAME([usr], [.]) -CHECK_DIR_NAME([/], [/]) -CHECK_DIR_NAME([.], [.]) -CHECK_DIR_NAME([..], [.]) -CHECK_DIR_NAME([//], [//]) # / is also allowed -CHECK_DIR_NAME([//foo], [//]) # / is also allowed -CHECK_DIR_NAME([], [.]) - -# Additional test cases. -CHECK_DIR_NAME([dir/file], [dir]) -CHECK_DIR_NAME([dir/file/], [dir]) -CHECK_DIR_NAME([dir/file//], [dir]) -CHECK_DIR_NAME([///foo], [/]) diff --git a/tests/file_name.at b/tests/file_name.at new file mode 100644 index 00000000..e0b43dca --- /dev/null +++ b/tests/file_name.at @@ -0,0 +1,26 @@ +AT_BANNER([test dir_name and base_name functions]) + +m4_define([CHECK_FILE_NAME], + [AT_SETUP([components of "$1" are "$2", "$3"]) + AT_KEYWORDS([dir_name base_name]) + AT_CHECK([test-file_name "AS_ESCAPE($1)"], [0], [$2 +$3 +]) + AT_CLEANUP]) + +# These are the test cases given in POSIX for dirname() and basename(). +CHECK_FILE_NAME([/usr/lib], [/usr], [lib]) +CHECK_FILE_NAME([/usr/], [/], [usr]) +CHECK_FILE_NAME([usr], [.], [usr]) +CHECK_FILE_NAME([/], [/], [/]) +CHECK_FILE_NAME([.], [.], [.]) +CHECK_FILE_NAME([..], [.], [..]) +CHECK_FILE_NAME([//], [//], [//]) # / is also allowed +CHECK_FILE_NAME([//foo], [//], [foo]) # / is also allowed for dirname +CHECK_FILE_NAME([], [.], [.]) + +# Additional test cases. +CHECK_FILE_NAME([dir/file], [dir], [file]) +CHECK_FILE_NAME([dir/file/], [dir], [file]) +CHECK_FILE_NAME([dir/file//], [dir], [file]) +CHECK_FILE_NAME([///foo], [/], [foo]) diff --git a/tests/test-dir_name.c b/tests/test-file_name.c similarity index 80% rename from tests/test-dir_name.c rename to tests/test-file_name.c index 627ecf17..a9d1ab94 100644 --- a/tests/test-dir_name.c +++ b/tests/test-file_name.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Nicira Networks. + * Copyright (c) 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,15 @@ main(int argc, char *argv[]) int i; for (i = 1; i < argc; i++) { - char *dir = dir_name(argv[i]); + char *dir, *base; + + dir = dir_name(argv[i]); puts(dir); free(dir); + + base = base_name(argv[i]); + puts(base); + free(base); } return 0; diff --git a/tests/testsuite.at b/tests/testsuite.at index d66563c8..c6468d85 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -44,7 +44,7 @@ m4_include([tests/daemon.at]) m4_include([tests/daemon-py.at]) m4_include([tests/ovs-ofctl.at]) m4_include([tests/vconn.at]) -m4_include([tests/dir_name.at]) +m4_include([tests/file_name.at]) m4_include([tests/aes128.at]) m4_include([tests/uuid.at]) m4_include([tests/json.at]) -- 2.30.2