aboutsummaryrefslogtreecommitdiffstats
path: root/android/utils/path.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/utils/path.c')
-rw-r--r--android/utils/path.c129
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.