1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gclib/utils.c Fri Jan 27 00:28:11 2012 +0000
1.3 @@ -0,0 +1,46 @@
1.4 +#include <stdlib.h>
1.5 +#include <string.h>
1.6 +#include <unistd.h>
1.7 +#include <gclib/mem.h>
1.8 +#include <gclib/strfuncs.h>
1.9 +#include <gclib/utils.h>
1.10 +
1.11 +#define is_valid_drive(d) ((d)>='a' && (d)<='z' || (d)>='A' && (d)<='Z')
1.12 +
1.13 +/*
1.14 + * Gets the last component of the filename. If filename ends with a directory
1.15 + * separator it gets the component before the last slash. If filename consists
1.16 + * only of directory separators (and on Windows, possibly a drive letter), a
1.17 + * single separator is returned. If filename is empty, it gets ".".
1.18 + */
1.19 +char *path_get_basename(const char *filename)
1.20 +{
1.21 + ssize_t base,last_nonslash;
1.22 + size_t len;
1.23 + char *retval;
1.24 + if (*filename=='\0')
1.25 + return str_dup(".");
1.26 + last_nonslash=strlen(filename)-1;
1.27 + while (last_nonslash>=0 && GC_IS_DIR_SEPARATOR(filename[last_nonslash]))
1.28 + last_nonslash--;
1.29 + if (last_nonslash<0)
1.30 + /* string only containing slashes */
1.31 + return str_dup(GC_DIR_SEPARATOR_S);
1.32 +#ifdef WIN32
1.33 + if (last_nonslash==1 && is_valid_drive(filename[0]) && filename[1]==':')
1.34 + /* string only containing slashes and a drive */
1.35 + return str_dup(GC_DIR_SEPARATOR_S);
1.36 +#endif
1.37 + base=last_nonslash;
1.38 + while (base>=0 && !GC_IS_DIR_SEPARATOR(filename[base]))
1.39 + base--;
1.40 +#ifdef WIN32
1.41 + if (base==-1 && is_valid_drive(filename[0]) && filename[1] == ':')
1.42 + base=1;
1.43 +#endif
1.44 + len=last_nonslash-base;
1.45 + retval=mem_alloc(len+1,1);
1.46 + memcpy(retval,filename+base+1,len);
1.47 + retval[len]='\0';
1.48 + return retval;
1.49 +}