diff options
Diffstat (limited to 'android/utils/path.c')
-rw-r--r-- | android/utils/path.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/android/utils/path.c b/android/utils/path.c index 9dd238e..b15b6de 100644 --- a/android/utils/path.c +++ b/android/utils/path.c @@ -101,6 +101,111 @@ path_parent( const char* path, int levels ) return result; } +static char* +substring_dup( const char* start, const char* end ) +{ + int len = end - start; + char* result = android_alloc(len+1); + memcpy(result, start, len); + result[len] = 0; + return result; +} + +int +path_split( const char* path, char* *pdirname, char* *pbasename ) +{ + const char* end = path + strlen(path); + const char* last; + char* basename; + + /* prepare for errors */ + if (pdirname) + *pdirname = NULL; + if (pbasename) + *pbasename = NULL; + + /* handle empty path case */ + if (end == path) { + return -1; + } + + /* strip trailing path separators */ + while (end > path && ispathsep(end[-1])) + end -= 1; + + /* handle "/" and degenerate cases like "////" */ + if (end == path) { + return -1; + } + + /* find last separator */ + last = end; + while (last > path && !ispathsep(last[-1])) + last -= 1; + + /* handle cases where there is no path separator */ + if (last == path) { + if (pdirname) + *pdirname = ASTRDUP("."); + if (pbasename) + *pbasename = substring_dup(path,end); + return 0; + } + + /* handle "/foo" */ + if (last == path+1) { + if (pdirname) + *pdirname = ASTRDUP("/"); + if (pbasename) + *pbasename = substring_dup(path+1,end); + return 0; + } + + /* compute basename */ + basename = substring_dup(last,end); + if (strcmp(basename, ".") == 0 || strcmp(basename, "..") == 0) { + AFREE(basename); + return -1; + } + + if (pbasename) + *pbasename = basename; + else { + AFREE(basename); + } + + /* compute dirname */ + if (pdirname != NULL) + *pdirname = substring_dup(path,last-1); + + return 0; +} + +char* +path_basename( const char* path ) +{ + char* basename; + + if (path_split(path, NULL, &basename) < 0) + return NULL; + + return basename; +} + +char* +path_dirname( const char* path ) +{ + char* dirname; + + if (path_split(path, &dirname, NULL) < 0) + return NULL; + + return dirname; +} + + + + /** MISC FILE AND DIRECTORY HANDLING **/ @@ -290,6 +395,30 @@ path_get_size( const char* path, uint64_t *psize ) } +ABool +path_is_absolute( const char* path ) +{ +#ifdef _WIN32 + if (path == NULL) + return 0; + + if (path[0] == '/' || path[0] == '\\') + return 1; + + /* 'C:' is always considered to be absolute + * even if used with a relative path like C:foo which + * is different from C:\foo + */ + if (path[0] != 0 && path[1] == ':') + return 1; + + return 0; +#else + return (path != NULL && path[0] == '/'); +#endif +} + + /** OTHER FILE UTILITIES ** ** path_empty_file() creates an empty file at a given path location. |