diff options
Diffstat (limited to 'winsup/mingw/mingwex/basename.c')
-rwxr-xr-x | winsup/mingw/mingwex/basename.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/winsup/mingw/mingwex/basename.c b/winsup/mingw/mingwex/basename.c new file mode 100755 index 000000000..768b9a0f4 --- /dev/null +++ b/winsup/mingw/mingwex/basename.c @@ -0,0 +1,103 @@ +/* basename.c + * + * $Id$ + * + * Provides an implementation of the "basename" function, conforming + * to SUSv3, with extensions to accommodate Win32 drive designators, + * and suitable for use on native Microsoft(R) Win32 platforms. + * + * Written by Keith Marshall <keithmarshall@users.sourceforge.net> + * + * This is free software. You may redistribute and/or modify it as you + * see fit, without restriction of copyright. + * + * This software is provided "as is", in the hope that it may be useful, + * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of + * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no + * time will the author accept any form of liability for any damages, + * however caused, resulting from the use of this software. + * + */ + +#include <stdio.h> +#include <string.h> +#include <libgen.h> + +#ifndef __cdecl /* If compiling on any non-Win32 platform ... */ +#define __cdecl /* this may not be defined. */ +#endif + +__cdecl char *basename( char *path ) +{ + char *retname; + static char retfail[] = "."; + + if( path && *path ) + { + /* step over the drive designator, if present ... + * (FIXME: maybe should confirm *path is a valid drive designator). + */ + + if( path[1] == ':' ) + path += 2; + + /* check again, just to ensure we still have a non-empty path name ... */ + + if( *path ) + { + /* and, when we do ... + * scan from left to right, to the char after the final dir separator + */ + + for( retname = path ; *path ; ++path ) + { + if( (*path == '/') || (*path == '\\') ) + { + /* we found a dir separator ... + * step over it, and any others which immediately follow it + */ + + while( (*path == '/') || (*path == '\\') ) + ++path; + + /* if we didn't reach the end of the path string ... */ + + if( *path ) + + /* then we have a new candidate for the base name */ + + retname = path; + + /* otherwise ... + * strip off any trailing dir separators which we found + */ + + else while( (path > retname) && ((*--path == '/') || (*path == '\\')) ) + *path = '\0'; + } + } + + /* retname now points at the resolved base name ... + * if it's not empty, then we return it as it is, otherwise ... + * we must have had only dir separators in the original path name, + * so we return "/". + */ + + return *retname ? retname : strcpy( retfail, "/" ); + } + + /* or we had an empty residual path name, after the drive designator, + * in which case we simply fall through ... + */ + } + + /* and, if we get to here ... + * the path name is either NULL, or it decomposes to an empty string; + * in either case, we return the default value of "." in our static buffer, + * (but strcpy it, just in case the caller trashed it after a previous call). + */ + + return strcpy( retfail, "." ); +} + +/* $RCSfile$: end of file */ |