ali@0: #include ali@0: #include ali@0: #include ali@0: #include ali@0: #include ali@0: #include ali@0: ali@0: #define is_valid_drive(d) ((d)>='a' && (d)<='z' || (d)>='A' && (d)<='Z') ali@0: ali@0: /* ali@0: * Gets the last component of the filename. If filename ends with a directory ali@0: * separator it gets the component before the last slash. If filename consists ali@0: * only of directory separators (and on Windows, possibly a drive letter), a ali@0: * single separator is returned. If filename is empty, it gets ".". ali@0: */ ali@0: char *path_get_basename(const char *filename) ali@0: { ali@0: ssize_t base,last_nonslash; ali@0: size_t len; ali@0: char *retval; ali@0: if (*filename=='\0') ali@0: return str_dup("."); ali@0: last_nonslash=strlen(filename)-1; ali@0: while (last_nonslash>=0 && GC_IS_DIR_SEPARATOR(filename[last_nonslash])) ali@0: last_nonslash--; ali@0: if (last_nonslash<0) ali@0: /* string only containing slashes */ ali@0: return str_dup(GC_DIR_SEPARATOR_S); ali@0: #ifdef WIN32 ali@0: if (last_nonslash==1 && is_valid_drive(filename[0]) && filename[1]==':') ali@0: /* string only containing slashes and a drive */ ali@0: return str_dup(GC_DIR_SEPARATOR_S); ali@0: #endif ali@0: base=last_nonslash; ali@0: while (base>=0 && !GC_IS_DIR_SEPARATOR(filename[base])) ali@0: base--; ali@0: #ifdef WIN32 ali@0: if (base==-1 && is_valid_drive(filename[0]) && filename[1] == ':') ali@0: base=1; ali@0: #endif ali@0: len=last_nonslash-base; ali@0: retval=mem_alloc(len+1,1); ali@0: memcpy(retval,filename+base+1,len); ali@0: retval[len]='\0'; ali@0: return retval; ali@0: }