1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1992-2010 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                                                                      *
20***********************************************************************/
21#pragma prototyped
22/*
23 * David Korn
24 * AT&T Bell Laboratories
25 *
26 * namebase pathname [suffix]
27 *
28 * print the namebase of a pathname
29 */
30
31static const char usage[] =
32"[-?\n@(#)$Id: basename (AT&T Research) 1999-04-10 $\n]"
33USAGE_LICENSE
34"[+NAME?basename - strip directory and suffix from filenames]"
35"[+DESCRIPTION?\bbasename\b removes all leading directory components "
36	"from the file name defined by \astring\a.  If the file name "
37	"defined by \astring\a has a suffix that ends in \asuffix\a, "
38	"it is removed as well.]"
39"[+?If \astring\a consists solely of \b/\b characters the output will "
40	"be a single \b/\b unless \bPATH_LEADING_SLASHES\b returned by "
41	"\bgetconf\b(1) is \b1\b and \astring\a consists of multiple "
42	"\b/\b characters in which case \b//\b will be output.  "
43	"Otherwise, trailing \b/\b characters are removed, and if "
44	"there are any remaining \b/\b characters in \astring\a, "
45	"all characters up to and including the last \b/\b are removed.  "
46	"Finally, if \asuffix\a is specified, and is identical the end "
47	"of \astring\a, these characters are removed.  The characters "
48	"not removed from \astring\a will be written to standard output.]"
49"\n"
50"\n string [suffix]\n"
51"\n"
52"[+EXIT STATUS?]{"
53        "[+0?Successful Completion.]"
54        "[+>0?An error occurred.]"
55"}"
56"[+SEE ALSO?\bdirname\b(1), \bgetconf\b(1), \bbasename\b(3)]"
57;
58
59
60#include <cmd.h>
61
62static void namebase(Sfio_t *outfile, register char *pathname, char *suffix)
63{
64	register char *first, *last;
65	register int n=0;
66	for(first=last=pathname; *last; last++);
67	/* back over trailing '/' */
68	if(last>first)
69		while(*--last=='/' && last > first);
70	if(last==first && *last=='/')
71	{
72		/* all '/' or "" */
73		if(*first=='/')
74			if(*++last=='/')	/* keep leading // */
75				last++;
76	}
77	else
78	{
79		for(first=last++;first>pathname && *first!='/';first--);
80		if(*first=='/')
81			first++;
82		/* check for trailing suffix */
83		if(suffix && (n=strlen(suffix)) && n<(last-first))
84		{
85			if(memcmp(last-n,suffix,n)==0)
86				last -=n;
87		}
88	}
89	if(last>first)
90		sfwrite(outfile,first,last-first);
91	sfputc(outfile,'\n');
92}
93
94int
95b_basename(int argc,register char *argv[], void* context)
96{
97	register int  n;
98
99	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
100	while (n = optget(argv, usage)) switch (n)
101	{
102	case ':':
103		error(2, "%s", opt_info.arg);
104		break;
105	case '?':
106		error(ERROR_usage(2), "%s", opt_info.arg);
107		break;
108	}
109	argv += opt_info.index;
110	argc -= opt_info.index;
111	if(error_info.errors || argc < 1 || argc > 2)
112		error(ERROR_usage(2), "%s", optusage(NiL));
113	namebase(sfstdout,argv[0],argv[1]);
114	return(0);
115}
116
117