Skip to content

Commit e1aff6f

Browse files
committed
util: New function base_name().
1 parent c214278 commit e1aff6f

8 files changed

Lines changed: 75 additions & 43 deletions

File tree

lib/util.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,14 @@ get_cwd(void)
395395
}
396396
}
397397

398+
static char *
399+
all_slashes_name(const char *s)
400+
{
401+
return xstrdup(s[0] == '/' && s[1] == '/' && s[2] != '/' ? "//"
402+
: s[0] == '/' ? "/"
403+
: ".");
404+
}
405+
398406
/* Returns the directory name portion of 'file_name' as a malloc()'d string,
399407
* similar to the POSIX dirname() function but thread-safe. */
400408
char *
@@ -410,15 +418,31 @@ dir_name(const char *file_name)
410418
while (len > 0 && file_name[len - 1] == '/') {
411419
len--;
412420
}
413-
if (!len) {
414-
return xstrdup((file_name[0] == '/'
415-
&& file_name[1] == '/'
416-
&& file_name[2] != '/') ? "//"
417-
: file_name[0] == '/' ? "/"
418-
: ".");
419-
} else {
420-
return xmemdup0(file_name, len);
421+
return len ? xmemdup0(file_name, len) : all_slashes_name(file_name);
422+
}
423+
424+
/* Returns the file name portion of 'file_name' as a malloc()'d string,
425+
* similar to the POSIX basename() function but thread-safe. */
426+
char *
427+
base_name(const char *file_name)
428+
{
429+
size_t end, start;
430+
431+
end = strlen(file_name);
432+
while (end > 0 && file_name[end - 1] == '/') {
433+
end--;
434+
}
435+
436+
if (!end) {
437+
return all_slashes_name(file_name);
421438
}
439+
440+
start = end;
441+
while (start > 0 && file_name[start - 1] != '/') {
442+
start--;
443+
}
444+
445+
return xmemdup0(file_name + start, end - start);
422446
}
423447

424448
/* If 'file_name' starts with '/', returns a copy of 'file_name'. Otherwise,

lib/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ int hexit_value(int c);
135135

136136
char *get_cwd(void);
137137
char *dir_name(const char *file_name);
138+
char *base_name(const char *file_name);
138139
char *abs_file_name(const char *dir, const char *file_name);
139140

140141
void ignore(bool x OVS_UNUSED);

tests/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/test-classifier
1010
/test-csum
1111
/test-dhcp-client
12-
/test-dir_name
12+
/test-file_name
1313
/test-flows
1414
/test-hash
1515
/test-hmap

tests/automake.mk

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ TESTSUITE_AT = \
1414
tests/daemon-py.at \
1515
tests/ovs-ofctl.at \
1616
tests/vconn.at \
17-
tests/dir_name.at \
17+
tests/file_name.at \
1818
tests/aes128.at \
1919
tests/uuid.at \
2020
tests/json.at \
@@ -65,7 +65,7 @@ lcov_wrappers = \
6565
tests/lcov/test-classifier \
6666
tests/lcov/test-csum \
6767
tests/lcov/test-dhcp-client \
68-
tests/lcov/test-dir_name \
68+
tests/lcov/test-file_name \
6969
tests/lcov/test-flows \
7070
tests/lcov/test-hash \
7171
tests/lcov/test-hmap \
@@ -114,7 +114,7 @@ valgrind_wrappers = \
114114
tests/valgrind/test-classifier \
115115
tests/valgrind/test-csum \
116116
tests/valgrind/test-dhcp-client \
117-
tests/valgrind/test-dir_name \
117+
tests/valgrind/test-file_name \
118118
tests/valgrind/test-flows \
119119
tests/valgrind/test-hash \
120120
tests/valgrind/test-hmap \
@@ -181,9 +181,9 @@ noinst_PROGRAMS += tests/test-csum
181181
tests_test_csum_SOURCES = tests/test-csum.c
182182
tests_test_csum_LDADD = lib/libopenvswitch.a
183183

184-
noinst_PROGRAMS += tests/test-dir_name
185-
tests_test_dir_name_SOURCES = tests/test-dir_name.c
186-
tests_test_dir_name_LDADD = lib/libopenvswitch.a
184+
noinst_PROGRAMS += tests/test-file_name
185+
tests_test_file_name_SOURCES = tests/test-file_name.c
186+
tests_test_file_name_LDADD = lib/libopenvswitch.a
187187

188188
noinst_PROGRAMS += tests/test-flows
189189
tests_test_flows_SOURCES = tests/test-flows.c

tests/dir_name.at

Lines changed: 0 additions & 25 deletions
This file was deleted.

tests/file_name.at

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
AT_BANNER([test dir_name and base_name functions])
2+
3+
m4_define([CHECK_FILE_NAME],
4+
[AT_SETUP([components of "$1" are "$2", "$3"])
5+
AT_KEYWORDS([dir_name base_name])
6+
AT_CHECK([test-file_name "AS_ESCAPE($1)"], [0], [$2
7+
$3
8+
])
9+
AT_CLEANUP])
10+
11+
# These are the test cases given in POSIX for dirname() and basename().
12+
CHECK_FILE_NAME([/usr/lib], [/usr], [lib])
13+
CHECK_FILE_NAME([/usr/], [/], [usr])
14+
CHECK_FILE_NAME([usr], [.], [usr])
15+
CHECK_FILE_NAME([/], [/], [/])
16+
CHECK_FILE_NAME([.], [.], [.])
17+
CHECK_FILE_NAME([..], [.], [..])
18+
CHECK_FILE_NAME([//], [//], [//]) # / is also allowed
19+
CHECK_FILE_NAME([//foo], [//], [foo]) # / is also allowed for dirname
20+
CHECK_FILE_NAME([], [.], [.])
21+
22+
# Additional test cases.
23+
CHECK_FILE_NAME([dir/file], [dir], [file])
24+
CHECK_FILE_NAME([dir/file/], [dir], [file])
25+
CHECK_FILE_NAME([dir/file//], [dir], [file])
26+
CHECK_FILE_NAME([///foo], [/], [foo])
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009 Nicira Networks.
2+
* Copyright (c) 2009, 2010 Nicira Networks.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,9 +24,15 @@ main(int argc, char *argv[])
2424
int i;
2525

2626
for (i = 1; i < argc; i++) {
27-
char *dir = dir_name(argv[i]);
27+
char *dir, *base;
28+
29+
dir = dir_name(argv[i]);
2830
puts(dir);
2931
free(dir);
32+
33+
base = base_name(argv[i]);
34+
puts(base);
35+
free(base);
3036
}
3137

3238
return 0;

tests/testsuite.at

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ m4_include([tests/daemon.at])
4444
m4_include([tests/daemon-py.at])
4545
m4_include([tests/ovs-ofctl.at])
4646
m4_include([tests/vconn.at])
47-
m4_include([tests/dir_name.at])
47+
m4_include([tests/file_name.at])
4848
m4_include([tests/aes128.at])
4949
m4_include([tests/uuid.at])
5050
m4_include([tests/json.at])

0 commit comments

Comments
 (0)