New dir_name() function plus tests.
authorBen Pfaff <blp@nicira.com>
Mon, 19 Oct 2009 21:04:14 +0000 (14:04 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 4 Nov 2009 23:24:40 +0000 (15:24 -0800)
lib/util.c
lib/util.h
tests/automake.mk
tests/dir_name.at [new file with mode: 0644]
tests/test-dir_name.c [new file with mode: 0644]
tests/testsuite.at

index 6c152e24d1231247af779557ca18de4e5b668ebe..65cb36087dc71e752e68d4cde17698aae940870a 100644 (file)
@@ -357,3 +357,29 @@ hexit_value(int c)
 
     NOT_REACHED();
 }
+
+/* Returns the directory name portion of 'file_name' as a malloc()'d string,
+ * similar to the POSIX dirname() function but thread-safe. */
+char *
+dir_name(const char *file_name)
+{
+    size_t len = strlen(file_name);
+    while (len > 0 && file_name[len - 1] == '/') {
+        len--;
+    }
+    while (len > 0 && file_name[len - 1] != '/') {
+        len--;
+    }
+    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);
+    }
+}
index afa43f62514e6e2234cb912ce4b0ca9d4286c08b..9e7b88f06825866358adca046f55108a6163b40a 100644 (file)
@@ -125,6 +125,8 @@ bool str_to_double(const char *, double *);
 
 int hexit_value(int c);
 
+char *dir_name(const char *file_name);
+
 #ifdef  __cplusplus
 }
 #endif
index 41f498fea4e8fe87707e12ae53dd43c0e60ff049..a9edee0e5ce0640acf6cf945e510f2201dd032c4 100644 (file)
@@ -8,6 +8,7 @@ TESTSUITE_AT = \
        tests/testsuite.at \
        tests/lcov-pre.at \
        tests/library.at \
+       tests/dir_name.at \
        tests/aes128.at \
        tests/uuid.at \
        tests/json.at \
@@ -54,6 +55,10 @@ 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-flows
 tests_test_flows_SOURCES = tests/test-flows.c
 tests_test_flows_LDADD = lib/libopenvswitch.a
diff --git a/tests/dir_name.at b/tests/dir_name.at
new file mode 100644 (file)
index 0000000..4555e52
--- /dev/null
@@ -0,0 +1,25 @@
+AT_BANNER([test dir_name function])
+
+m4_define([CHECK_DIR_NAME],
+  [AT_SETUP([dir_name("$1") returns "$2"])
+   AT_KEYWORDS([dir_name])
+   OVS_CHECK_LCOV([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/test-dir_name.c b/tests/test-dir_name.c
new file mode 100644 (file)
index 0000000..627ecf1
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2009 Nicira Networks.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include "util.h"
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+    int i;
+
+    for (i = 1; i < argc; i++) {
+        char *dir = dir_name(argv[i]);
+        puts(dir);
+        free(dir);
+    }
+
+    return 0;
+}
index ca453155cc7a0fb30ee5e16da23ef3b3df390b93..816bed1c023eba3106de5bc327a4a34b2a52b653 100644 (file)
@@ -19,6 +19,7 @@ AT_TESTED([ovs-vsctl])
 
 m4_include([tests/lcov-pre.at])
 m4_include([tests/library.at])
+m4_include([tests/dir_name.at])
 m4_include([tests/aes128.at])
 m4_include([tests/uuid.at])
 m4_include([tests/json.at])