Add dirname function
This commit is contained in:
parent
a89d141e90
commit
3ec29ae85e
29
lib/other/dirname.c
Executable file
29
lib/other/dirname.c
Executable file
@ -0,0 +1,29 @@
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
|
||||
/* based on http://www.opengroup.org/onlinepubs/009695399/functions/dirname.html */
|
||||
char *dirname(char *path)
|
||||
{
|
||||
char *pathend;
|
||||
|
||||
/* remove leading slash(es) except root */
|
||||
pathend = path + strlen(path) - 1;
|
||||
while (pathend > path && *pathend == '/')
|
||||
pathend--;
|
||||
|
||||
/* remove last path component */
|
||||
while (pathend >= path && *pathend != '/')
|
||||
pathend--;
|
||||
|
||||
/* remove slash(es) before last path component except root */
|
||||
while (pathend > path && *pathend == '/')
|
||||
pathend--;
|
||||
|
||||
/* special case: no slashes */
|
||||
if (pathend < path)
|
||||
return ".";
|
||||
|
||||
/* truncate and return string */
|
||||
pathend[1] = 0;
|
||||
return path;
|
||||
}
|
19
man/man3/dirname.3
Executable file
19
man/man3/dirname.3
Executable file
@ -0,0 +1,19 @@
|
||||
.TH DIRNAME 3
|
||||
.SH NAME
|
||||
dirname \- determine name of containing directory
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ft B
|
||||
#include <libgen.h>
|
||||
|
||||
char *dirname(char *\fIpath\fP);
|
||||
.SH DESCRIPTION
|
||||
The dirname function returns the name of the directory containing \fIpath\fP.
|
||||
If the path does not contain slashes, the string "." is returned. Trailing
|
||||
slashes are ignored.
|
||||
.SH "SEE ALSO"
|
||||
.BR basename (3).
|
||||
.SH NOTES
|
||||
This function may, but need not, overwrite the buffer passed to it.
|
||||
Although MINIX' implementation of this function is re-entrant, POSIX does not
|
||||
guarantee this property and portable programs should not rely on it.
|
@ -3,6 +3,7 @@
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -328,6 +329,36 @@ static void cleanup(const char *path)
|
||||
if (rmdir(path) < 0) ERR;
|
||||
}
|
||||
|
||||
static void test_dirname(const char *path, const char *exp)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
int i, j;
|
||||
size_t pathlen = strlen(path);
|
||||
char *pathout;
|
||||
|
||||
assert(pathlen + 3 < PATH_MAX);
|
||||
|
||||
/* try with no, one or two trailing slashes */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* no trailing slashes for empty string */
|
||||
if (pathlen < 1 && i > 0)
|
||||
continue;
|
||||
|
||||
/* prepare buffer */
|
||||
strcpy(buffer, path);
|
||||
for (j = 0; j < i; j++)
|
||||
buffer[pathlen + j] = '/';
|
||||
|
||||
buffer[pathlen + i] = 0;
|
||||
|
||||
/* perform test */
|
||||
pathout = dirname(buffer);
|
||||
if (strcmp(pathout, exp) != 0)
|
||||
ERR;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char buffer1[PATH_MAX + 1], buffer2[PATH_MAX + 1];
|
||||
@ -358,6 +389,36 @@ int main(int argc, char **argv)
|
||||
/* delete the symlinks */
|
||||
cleanup(addbasepath(buffer1, PATH_BASE));
|
||||
|
||||
/* also test dirname */
|
||||
test_dirname("", ".");
|
||||
test_dirname(".", ".");
|
||||
test_dirname("..", ".");
|
||||
test_dirname("x", ".");
|
||||
test_dirname("xy", ".");
|
||||
test_dirname("x/y", "x");
|
||||
test_dirname("xy/z", "xy");
|
||||
test_dirname("x/yz", "x");
|
||||
test_dirname("ab/cd", "ab");
|
||||
test_dirname("x//y", "x");
|
||||
test_dirname("xy//z", "xy");
|
||||
test_dirname("x//yz", "x");
|
||||
test_dirname("ab//cd", "ab");
|
||||
test_dirname("/", "/");
|
||||
test_dirname("/x", "/");
|
||||
test_dirname("/xy", "/");
|
||||
test_dirname("/x/y", "/x");
|
||||
test_dirname("/xy/z", "/xy");
|
||||
test_dirname("/x/yz", "/x");
|
||||
test_dirname("/ab/cd", "/ab");
|
||||
test_dirname("/x//y", "/x");
|
||||
test_dirname("/xy//z", "/xy");
|
||||
test_dirname("/x//yz", "/x");
|
||||
test_dirname("/ab//cd", "/ab");
|
||||
test_dirname("/usr/src", "/usr");
|
||||
test_dirname("/usr/src/test", "/usr/src");
|
||||
test_dirname("usr/src", "usr");
|
||||
test_dirname("usr/src/test", "usr/src");
|
||||
|
||||
/* done */
|
||||
quit();
|
||||
return(-1); /* impossible */
|
||||
|
Loading…
x
Reference in New Issue
Block a user