gclib/utils.c
author ali <ali@juiblex.co.uk>
Thu Jan 26 23:35:52 2012 +0000 (2012-01-26)
changeset 3 ec364358631b
permissions -rw-r--r--
Non-win32 platforms might need mkstemp too
     1 #include <stdlib.h>
     2 #include <string.h>
     3 #include <unistd.h>
     4 #include <gclib/mem.h>
     5 #include <gclib/strfuncs.h>
     6 #include <gclib/utils.h>
     7 
     8 #define is_valid_drive(d)	((d)>='a' && (d)<='z' || (d)>='A' && (d)<='Z')
     9 
    10 /*
    11  * Gets the last component of the filename. If filename ends with a directory
    12  * separator it gets the component before the last slash. If filename consists
    13  * only of directory separators (and on Windows, possibly a drive letter), a
    14  * single separator is returned. If filename is empty, it gets ".".
    15  */
    16 char *path_get_basename(const char *filename)
    17 {
    18     ssize_t base,last_nonslash;
    19     size_t len;
    20     char *retval;
    21     if (*filename=='\0')
    22         return str_dup(".");
    23     last_nonslash=strlen(filename)-1;
    24     while (last_nonslash>=0 && GC_IS_DIR_SEPARATOR(filename[last_nonslash]))
    25 	last_nonslash--;
    26     if (last_nonslash<0)
    27 	/* string only containing slashes */
    28     return str_dup(GC_DIR_SEPARATOR_S);
    29 #ifdef WIN32
    30     if (last_nonslash==1 && is_valid_drive(filename[0]) && filename[1]==':')
    31 	/* string only containing slashes and a drive */
    32 	return str_dup(GC_DIR_SEPARATOR_S);
    33 #endif
    34     base=last_nonslash;
    35     while (base>=0 && !GC_IS_DIR_SEPARATOR(filename[base]))
    36 	base--;
    37 #ifdef WIN32
    38     if (base==-1 && is_valid_drive(filename[0]) && filename[1] == ':')
    39 	  base=1;
    40 #endif
    41     len=last_nonslash-base;
    42     retval=mem_alloc(len+1,1);
    43     memcpy(retval,filename+base+1,len);
    44     retval[len]='\0';
    45     return retval;
    46 }