diff --git a/misc/path_utils.c b/misc/path_utils.c index 8c0f3c6e39644..ec6ec40a9eefc 100644 --- a/misc/path_utils.c +++ b/misc/path_utils.c @@ -85,15 +85,26 @@ void mp_path_strip_trailing_separator(char *path) char *mp_splitext(const char *path, bstr *root) { mp_assert(path); - int skip = (*path == '.'); // skip leading dot for "hidden" unix files - const char *split = strrchr(path + skip, '.'); - if (!split || !split[1] || strchr(split, '/')) + char *bn = mp_basename(path); + + // Skip all leading dots, not just for "hidden" unix files, otherwise we + // end up splitting a part of the filename sans leading dot. + bn += strspn(bn, "."); + + const char *split = strrchr(bn, '.'); + if (!split || !split[1]) return NULL; if (root) *root = (bstr){(char *)path, split - path}; return (char *)split + 1; } +char *mp_strip_ext(void *talloc_ctx, const char *s) +{ + bstr root; + return mp_splitext(s, &root) ? bstrto0(talloc_ctx, root) : talloc_strdup(talloc_ctx, s); +} + bool mp_path_is_absolute(struct bstr path) { if (path.len && strchr(mp_path_separators, path.start[0])) diff --git a/misc/path_utils.h b/misc/path_utils.h index 1e6c16ac66e99..530e535d1144e 100644 --- a/misc/path_utils.h +++ b/misc/path_utils.h @@ -33,6 +33,9 @@ char *mp_basename(const char *path); */ char *mp_splitext(const char *path, bstr *root); +// This is a shorthand to remove the extension +char *mp_strip_ext(void *talloc_ctx, const char *s); + /* Return struct bstr referencing directory part of path, or if that * would be empty, ".". */ diff --git a/player/command.c b/player/command.c index 2761d70750a61..b5d28bafe9f13 100644 --- a/player/command.c +++ b/player/command.c @@ -536,9 +536,7 @@ static int mp_property_filename(void *ctx, struct m_property *prop, if (strcmp(ka->key, "no-ext") == 0) { action = ka->action; arg = ka->arg; - bstr root; - if (mp_splitext(f, &root)) - f = bstrto0(filename, root); + f = mp_strip_ext(filename, f); } } int r = m_property_strdup_ro(action, arg, f); diff --git a/player/screenshot.c b/player/screenshot.c index 665b41d6a94f0..9f87244e6d5d4 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -69,14 +69,6 @@ void screenshot_init(struct MPContext *mpctx) }; } -static char *stripext(void *talloc_ctx, const char *s) -{ - const char *end = strrchr(s, '.'); - if (!end) - end = s + strlen(s); - return talloc_asprintf(talloc_ctx, "%.*s", (int)(end - s), s); -} - static bool write_screenshot(struct mp_cmd_ctx *cmd, struct mp_image *img, const char *filename, struct image_writer_opts *opts, bool overwrite) @@ -176,20 +168,20 @@ static char *create_fname(struct MPContext *mpctx, char *template, } case 'f': case 'F': { - char *video_file = NULL; - if (mpctx->filename) { - if (mp_is_url(bstr0(mpctx->filename))) - video_file = mp_basename(mp_url_unescape(res, mpctx->filename)); - else - video_file = mp_basename(mpctx->filename); + char *name; + if (!mpctx->filename) { + name = "NO_FILE"; + } else if (bstr_endswith0(bstr0(mpctx->filename), "/")) { + name = mpctx->filename; + } else { + name = mp_basename(mpctx->filename); } - if (!video_file) - video_file = "NO_FILE"; + if (mp_is_url(bstr0(mpctx->filename))) + name = mp_url_unescape(res, name); - char *name = video_file; if (fmt == 'F') - name = stripext(res, video_file); + name = mp_strip_ext(res, name); append_filename(&res, name); break; } @@ -305,9 +297,6 @@ static char *gen_fname(struct mp_cmd_ctx *cmd, const char *file_ext) void *t = fname; dir = mp_get_user_path(t, ctx->mpctx->global, dir); fname = mp_path_join(NULL, dir, fname); - - mp_mkdirp(dir); - talloc_free(t); }