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 |
}
|