diff options
author | nanahi <130121847+na-na-hi@users.noreply.github.com> | 2024-02-19 04:11:25 -0500 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2024-02-23 21:35:57 +0100 |
commit | 4e73602ae5374f271dd638a4eda4f9c95d196488 (patch) | |
tree | 8c6fd31c6c929675b2d2c3fdeced1d0d6e0a4b60 /options | |
parent | 84015959cc5d36d8973b2f07ece066902bbbdbe7 (diff) | |
download | mpv-4e73602ae5374f271dd638a4eda4f9c95d196488.tar.bz2 mpv-4e73602ae5374f271dd638a4eda4f9c95d196488.tar.xz |
options/path: move path utility functions to misc/path_utils
These utility functions have nothing to do with user and config dir/file.
Move them to a separate file.
Diffstat (limited to 'options')
-rw-r--r-- | options/path.c | 185 | ||||
-rw-r--r-- | options/path.h | 41 |
2 files changed, 2 insertions, 224 deletions
diff --git a/options/path.c b/options/path.c index 52dc113b73..c9512a8b1f 100644 --- a/options/path.c +++ b/options/path.c @@ -29,6 +29,7 @@ #include "config.h" +#include "misc/path_utils.h" #include "common/common.h" #include "common/global.h" #include "common/msg.h" @@ -217,190 +218,6 @@ char *mp_get_user_path(void *talloc_ctx, struct mpv_global *global, return res; } -char *mp_basename(const char *path) -{ - char *s; - -#if HAVE_DOS_PATHS - if (!mp_is_url(bstr0(path))) { - s = strrchr(path, '\\'); - if (s) - path = s + 1; - s = strrchr(path, ':'); - if (s) - path = s + 1; - } -#endif - s = strrchr(path, '/'); - return s ? s + 1 : (char *)path; -} - -struct bstr mp_dirname(const char *path) -{ - struct bstr ret = { - (uint8_t *)path, mp_basename(path) - path - }; - if (ret.len == 0) - return bstr0("."); - return ret; -} - - -#if HAVE_DOS_PATHS -static const char mp_path_separators[] = "\\/"; -#else -static const char mp_path_separators[] = "/"; -#endif - -// Mutates path and removes a trailing '/' (or '\' on Windows) -void mp_path_strip_trailing_separator(char *path) -{ - size_t len = strlen(path); - if (len > 0 && strchr(mp_path_separators, path[len - 1])) - path[len - 1] = '\0'; -} - -char *mp_splitext(const char *path, bstr *root) -{ - assert(path); - int skip = (*path == '.'); // skip leading dot for "hidden" unix files - const char *split = strrchr(path + skip, '.'); - if (!split || !split[1] || strchr(split, '/')) - return NULL; - if (root) - *root = (bstr){(char *)path, split - path}; - return (char *)split + 1; -} - -bool mp_path_is_absolute(struct bstr path) -{ - if (path.len && strchr(mp_path_separators, path.start[0])) - return true; - -#if HAVE_DOS_PATHS - // Note: "X:filename" is a path relative to the current working directory - // of drive X, and thus is not an absolute path. It needs to be - // followed by \ or /. - if (path.len >= 3 && path.start[1] == ':' && - strchr(mp_path_separators, path.start[2])) - return true; -#endif - - return false; -} - -char *mp_path_join_bstr(void *talloc_ctx, struct bstr p1, struct bstr p2) -{ - if (p1.len == 0) - return bstrdup0(talloc_ctx, p2); - if (p2.len == 0) - return bstrdup0(talloc_ctx, p1); - - if (mp_path_is_absolute(p2)) - return bstrdup0(talloc_ctx, p2); - - bool have_separator = strchr(mp_path_separators, p1.start[p1.len - 1]); -#if HAVE_DOS_PATHS - // "X:" only => path relative to "X:" current working directory. - if (p1.len == 2 && p1.start[1] == ':') - have_separator = true; -#endif - - return talloc_asprintf(talloc_ctx, "%.*s%s%.*s", BSTR_P(p1), - have_separator ? "" : "/", BSTR_P(p2)); -} - -char *mp_path_join(void *talloc_ctx, const char *p1, const char *p2) -{ - return mp_path_join_bstr(talloc_ctx, bstr0(p1), bstr0(p2)); -} - -char *mp_getcwd(void *talloc_ctx) -{ - char *e_wd = getenv("PWD"); - if (e_wd) - return talloc_strdup(talloc_ctx, e_wd); - - char *wd = talloc_array(talloc_ctx, char, 20); - while (getcwd(wd, talloc_get_size(wd)) == NULL) { - if (errno != ERANGE) { - talloc_free(wd); - return NULL; - } - wd = talloc_realloc(talloc_ctx, wd, char, talloc_get_size(wd) * 2); - } - return wd; -} - -char *mp_normalize_path(void *talloc_ctx, const char *path) -{ - if (mp_is_url(bstr0(path))) - return talloc_strdup(talloc_ctx, path); - - return mp_path_join(talloc_ctx, mp_getcwd(talloc_ctx), path); -} - -bool mp_path_exists(const char *path) -{ - struct stat st; - return path && stat(path, &st) == 0; -} - -bool mp_path_isdir(const char *path) -{ - struct stat st; - return stat(path, &st) == 0 && S_ISDIR(st.st_mode); -} - -// Return false if it's considered a normal local filesystem path. -bool mp_is_url(bstr path) -{ - int proto = bstr_find0(path, "://"); - if (proto < 1) - return false; - // Per RFC3986, the first character of the protocol must be alphabetic. - // The rest must be alphanumeric plus -, + and . - for (int i = 0; i < proto; i++) { - unsigned char c = path.start[i]; - if ((i == 0 && !mp_isalpha(c)) || - (!mp_isalnum(c) && c != '.' && c != '-' && c != '+')) - { - return false; - } - } - return true; -} - -// Return the protocol part of path, e.g. "http" if path is "http://...". -// On success, out_url (if not NULL) is set to the part after the "://". -bstr mp_split_proto(bstr path, bstr *out_url) -{ - if (!mp_is_url(path)) - return (bstr){0}; - bstr r; - bstr_split_tok(path, "://", &r, out_url ? out_url : &(bstr){0}); - return r; -} - -void mp_mkdirp(const char *dir) -{ - char *path = talloc_strdup(NULL, dir); - char *cdir = path + 1; - - while (cdir) { - cdir = strchr(cdir, '/'); - if (cdir) - *cdir = 0; - - mkdir(path, 0700); - - if (cdir) - *cdir++ = '/'; - } - - talloc_free(path); -} - void mp_mk_user_dir(struct mpv_global *global, const char *type, char *subdir) { char *dir = mp_find_user_file(NULL, global, type, subdir); diff --git a/options/path.h b/options/path.h index 1bdfeb7566..a665e67b48 100644 --- a/options/path.h +++ b/options/path.h @@ -22,6 +22,7 @@ #include <stdbool.h> #include "misc/bstr.h" +#include "misc/path_utils.h" struct mpv_global; struct MPOpts; @@ -53,46 +54,6 @@ char **mp_find_all_config_files(void *talloc_ctx, struct mpv_global *global, char *mp_get_user_path(void *talloc_ctx, struct mpv_global *global, const char *path); -// Return pointer to filename part of path - -char *mp_basename(const char *path); - -/* Return file extension, excluding the '.'. If root is not NULL, set it to the - * part of the path without extension. So: path == root + "." + extension - * Don't consider it a file extension if the only '.' is the first character. - * Return NULL if no extension and don't set *root in this case. - */ -char *mp_splitext(const char *path, bstr *root); - -/* Return struct bstr referencing directory part of path, or if that - * would be empty, ".". - */ -struct bstr mp_dirname(const char *path); - -void mp_path_strip_trailing_separator(char *path); - -/* Join two path components and return a newly allocated string - * for the result. '/' is inserted between the components if needed. - * If p2 is an absolute path then the value of p1 is ignored. - */ -char *mp_path_join(void *talloc_ctx, const char *p1, const char *p2); -char *mp_path_join_bstr(void *talloc_ctx, struct bstr p1, struct bstr p2); - -// Return whether the path is absolute. -bool mp_path_is_absolute(struct bstr path); - -char *mp_getcwd(void *talloc_ctx); - -char *mp_normalize_path(void *talloc_ctx, const char *path); - -bool mp_path_exists(const char *path); -bool mp_path_isdir(const char *path); - -bool mp_is_url(bstr path); - -bstr mp_split_proto(bstr path, bstr *out_url); - -void mp_mkdirp(const char *dir); void mp_mk_user_dir(struct mpv_global *global, const char *type, char *subdir); #endif /* MPLAYER_PATH_H */ |