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