xref: /netbsd-src/usr.bin/basename/basename.c (revision e9d867ef5010fbab8d48045c13025636f5cd7479)
1 /*-
2  * Copyright (c) 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #ifndef lint
35 char copyright[] =
36 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
37  All rights reserved.\n";
38 #endif /* not lint */
39 
40 #ifndef lint
41 /*static char sccsid[] = "from: @(#)basename.c	5.1 (Berkeley) 3/9/91";*/
42 static char rcsid[] = "$Id: basename.c,v 1.2 1993/08/01 18:18:23 mycroft Exp $";
43 #endif /* not lint */
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 
49 main(argc, argv)
50 	int argc;
51 	char **argv;
52 {
53 	extern int optind;
54 	register char *p;
55 	int ch;
56 
57 	while ((ch = getopt(argc, argv, "")) != EOF)
58 		switch(ch) {
59 		case '?':
60 		default:
61 			usage();
62 		}
63 	argc -= optind;
64 	argv += optind;
65 
66 	if (argc != 1 && argc != 2)
67 		usage();
68 
69 	/*
70 	 * (1) If string is // it is implementation defined whether steps (2)
71 	 *     through (5) are skipped or processed.
72 	 *
73 	 * (2) If string consists entirely of slash characters, string shall
74 	 *     be set to a single slash character.  In this case, skip steps
75 	 *     (3) through (5).
76 	 */
77 	for (p = *argv;; ++p) {
78 		if (!*p) {
79 			if (p > *argv)
80 				(void)printf("/\n");
81 			else
82 				(void)printf("\n");
83 			exit(0);
84 		}
85 		if (*p != '/')
86 			break;
87 	}
88 
89 	/*
90 	 * (3) If there are any trailing slash characters in string, they
91 	 *     shall be removed.
92 	 */
93 	for (; *p; ++p);
94 	while (*--p == '/');
95 	*++p = '\0';
96 
97 	/*
98 	 * (4) If there are any slash characters remaining in string, the
99 	 *     prefix of string up to an including the last slash character
100 	 *     in string shall be removed.
101 	 */
102 	while (--p >= *argv)
103 		if (*p == '/')
104 			break;
105 	++p;
106 
107 	/*
108 	 * (5) If the suffix operand is present, is not identical to the
109 	 *     characters remaining in string, and is identical to a suffix
110 	 *     of the characters remaining in string, the suffix suffix
111 	 *     shall be removed from string.
112 	 */
113 	if (*++argv) {
114 		int suffixlen, stringlen, off;
115 
116 		suffixlen = strlen(*argv);
117 		stringlen = strlen(p);
118 
119 		if (suffixlen < stringlen) {
120 			off = stringlen - suffixlen;
121 			if (!strcmp(p + off, *argv))
122 				p[off] = '\0';
123 		}
124 	}
125 	(void)printf("%s\n", p);
126 	exit(0);
127 }
128 
129 usage()
130 {
131 	(void)fprintf(stderr, "usage: basename string [suffix]\n");
132 	exit(1);
133 }
134