xref: /dragonfly/contrib/bmake/dirname.c (revision ca58f742)
1ca58f742SDaniel Fojt /*	$NetBSD: dirname.c,v 1.14 2018/09/27 00:45:34 kre Exp $	*/
201e196c8SJohn Marino 
301e196c8SJohn Marino /*-
401e196c8SJohn Marino  * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
501e196c8SJohn Marino  * All rights reserved.
601e196c8SJohn Marino  *
701e196c8SJohn Marino  * This code is derived from software contributed to The NetBSD Foundation
801e196c8SJohn Marino  * by Klaus Klein and Jason R. Thorpe.
901e196c8SJohn Marino  *
1001e196c8SJohn Marino  * Redistribution and use in source and binary forms, with or without
1101e196c8SJohn Marino  * modification, are permitted provided that the following conditions
1201e196c8SJohn Marino  * are met:
1301e196c8SJohn Marino  * 1. Redistributions of source code must retain the above copyright
1401e196c8SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1501e196c8SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1601e196c8SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1701e196c8SJohn Marino  *    documentation and/or other materials provided with the distribution.
1801e196c8SJohn Marino  *
1901e196c8SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2001e196c8SJohn Marino  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2101e196c8SJohn Marino  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2201e196c8SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2301e196c8SJohn Marino  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2401e196c8SJohn Marino  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2501e196c8SJohn Marino  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2601e196c8SJohn Marino  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2701e196c8SJohn Marino  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2801e196c8SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2901e196c8SJohn Marino  * POSSIBILITY OF SUCH DAMAGE.
3001e196c8SJohn Marino  */
3101e196c8SJohn Marino 
3201e196c8SJohn Marino #ifdef HAVE_CONFIG_H
3301e196c8SJohn Marino # include <config.h>
3401e196c8SJohn Marino #endif
3501e196c8SJohn Marino #ifndef HAVE_DIRNAME
3601e196c8SJohn Marino 
3701e196c8SJohn Marino #include <sys/cdefs.h>
38ca58f742SDaniel Fojt #if defined(LIBC_SCCS) && !defined(lint)
39ca58f742SDaniel Fojt __RCSID("$NetBSD: dirname.c,v 1.14 2018/09/27 00:45:34 kre Exp $");
40ca58f742SDaniel Fojt #endif /* !LIBC_SCCS && !lint */
41ca58f742SDaniel Fojt 
42f445c897SJohn Marino #include <sys/param.h>
43f445c897SJohn Marino #ifdef HAVE_LIBGEN_H
44f445c897SJohn Marino #include <libgen.h>
45f445c897SJohn Marino #endif
4601e196c8SJohn Marino #ifdef HAVE_LIMITS_H
4701e196c8SJohn Marino #include <limits.h>
4801e196c8SJohn Marino #endif
4901e196c8SJohn Marino #ifdef HAVE_STRING_H
5001e196c8SJohn Marino #include <string.h>
5101e196c8SJohn Marino #endif
5201e196c8SJohn Marino #ifndef PATH_MAX
5301e196c8SJohn Marino # define PATH_MAX 1024
5401e196c8SJohn Marino #endif
55f445c897SJohn Marino #ifndef MIN
56f445c897SJohn Marino # define MIN(a, b) ((a < b) ? a : b)
57f445c897SJohn Marino #endif
5801e196c8SJohn Marino 
59f445c897SJohn Marino 
60f445c897SJohn Marino static size_t
xdirname_r(const char * path,char * buf,size_t buflen)61f445c897SJohn Marino xdirname_r(const char *path, char *buf, size_t buflen)
6201e196c8SJohn Marino {
63f445c897SJohn Marino 	const char *endp;
6401e196c8SJohn Marino 	size_t len;
6501e196c8SJohn Marino 
6601e196c8SJohn Marino 	/*
6701e196c8SJohn Marino 	 * If `path' is a null pointer or points to an empty string,
6801e196c8SJohn Marino 	 * return a pointer to the string ".".
6901e196c8SJohn Marino 	 */
70f445c897SJohn Marino 	if (path == NULL || *path == '\0') {
71f445c897SJohn Marino 		path = ".";
72f445c897SJohn Marino 		len = 1;
73f445c897SJohn Marino 		goto out;
74f445c897SJohn Marino 	}
7501e196c8SJohn Marino 
7601e196c8SJohn Marino 	/* Strip trailing slashes, if any. */
77f445c897SJohn Marino 	endp = path + strlen(path) - 1;
78f445c897SJohn Marino 	while (endp != path && *endp == '/')
79f445c897SJohn Marino 		endp--;
8001e196c8SJohn Marino 
81f445c897SJohn Marino 	/* Find the start of the dir */
82f445c897SJohn Marino 	while (endp > path && *endp != '/')
83f445c897SJohn Marino 		endp--;
8401e196c8SJohn Marino 
85f445c897SJohn Marino 	if (endp == path) {
86f445c897SJohn Marino 		path = *endp == '/' ? "/" : ".";
87f445c897SJohn Marino 		len = 1;
88f445c897SJohn Marino 		goto out;
8901e196c8SJohn Marino 	}
9001e196c8SJohn Marino 
91f445c897SJohn Marino 	do
92f445c897SJohn Marino 		endp--;
93f445c897SJohn Marino 	while (endp > path && *endp == '/');
9401e196c8SJohn Marino 
95f445c897SJohn Marino 	len = endp - path + 1;
96f445c897SJohn Marino out:
97f445c897SJohn Marino 	if (buf != NULL && buflen != 0) {
98f445c897SJohn Marino 		buflen = MIN(len, buflen - 1);
99ca58f742SDaniel Fojt 		if (buf != path)
100f445c897SJohn Marino 			memcpy(buf, path, buflen);
101f445c897SJohn Marino 		buf[buflen] = '\0';
10201e196c8SJohn Marino 	}
103f445c897SJohn Marino 	return len;
104f445c897SJohn Marino }
105f445c897SJohn Marino 
106f445c897SJohn Marino char *
dirname(char * path)107f445c897SJohn Marino dirname(char *path)
108f445c897SJohn Marino {
109f445c897SJohn Marino 	static char result[PATH_MAX];
110f445c897SJohn Marino 	(void)xdirname_r(path, result, sizeof(result));
111f445c897SJohn Marino 	return result;
112f445c897SJohn Marino }
113f445c897SJohn Marino 
114f445c897SJohn Marino #ifdef MAIN
115f445c897SJohn Marino #include <stdlib.h>
116f445c897SJohn Marino #include <stdio.h>
117f445c897SJohn Marino 
118f445c897SJohn Marino int
main(int argc,char * argv[])119f445c897SJohn Marino main(int argc, char *argv[])
120f445c897SJohn Marino {
121f445c897SJohn Marino 	printf("%s\n", dirname(argv[1]));
122f445c897SJohn Marino 	exit(0);
123f445c897SJohn Marino }
124f445c897SJohn Marino #endif
12501e196c8SJohn Marino #endif
126