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