Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions demux/demux_playlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,14 @@ static int parse_m3u(struct pl_parser *p)
if (p->probing && !bstr_equals0(line, "#EXTM3U")) {
// Last resort: if the file extension is m3u, it might be headerless.
if (p->check_level == DEMUX_CHECK_UNSAFE) {
char *ext = mp_splitext(p->real_stream->url, NULL);
bstr ext = bstr_get_ext(bstr0(p->real_stream->url));
char probe[PROBE_SIZE];
int len = stream_read_peek(p->real_stream, probe, sizeof(probe));
bstr data = {probe, len};
if (ext && data.len >= 2 && maybe_text(data)) {
if (ext.len && data.len >= 2 && maybe_text(data)) {
const char *exts[] = {"m3u", "m3u8", NULL};
for (int n = 0; exts[n]; n++) {
if (strcasecmp(ext, exts[n]) == 0)
if (bstrcasecmp(ext, bstr0(exts[n])) == 0)
goto ok;
}
}
Expand Down
16 changes: 0 additions & 16 deletions misc/bstr.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,22 +414,6 @@ bool bstr_case_endswith(struct bstr s, struct bstr suffix)
return end.len == suffix.len && bstrcasecmp(end, suffix) == 0;
}

struct bstr bstr_strip_ext(struct bstr str)
{
int dotpos = bstrrchr(str, '.');
if (dotpos < 0)
return str;
return (struct bstr){str.start, dotpos};
}

struct bstr bstr_get_ext(struct bstr s)
{
int dotpos = bstrrchr(s, '.');
if (dotpos < 0)
return (struct bstr){NULL, 0};
return bstr_splice(s, dotpos + 1, s.len);
}

static int h_to_i(unsigned char c)
{
if (c >= '0' && c <= '9')
Expand Down
63 changes: 40 additions & 23 deletions misc/path_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,29 @@
#include <pathcch.h>
#endif

const char *mp_basename(const char *path)
bstr mp_basename_bstr(bstr path)
{
const char *s;
int separator_pos;

#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;
if (!mp_is_url(path)) {
separator_pos = bstrrchr(path, '\\');
if (separator_pos >= 0)
path = bstr_splice(path, separator_pos + 1, path.len);
separator_pos = bstrrchr(path, ':');
if (separator_pos >= 0)
path = bstr_splice(path, separator_pos + 1, path.len);
}
#endif
s = strrchr(path, '/');
return s ? s + 1 : path;
separator_pos = bstrrchr(path, '/');
if (separator_pos < 0)
return path;
return bstr_splice(path, separator_pos + 1, path.len);
}

const char *mp_basename(const char *path)
{
return mp_basename_bstr(bstr0(path)).start;
}

struct bstr mp_dirname(const char *path)
Expand Down Expand Up @@ -82,27 +89,37 @@ void mp_path_strip_trailing_separator(char *path)
path[len - 1] = '\0';
}

char *mp_splitext(const char *path, bstr *root)
/* Return the file extension, excluding the '.'. If root is not NULL, set it to
* the part of the path without extension. So: path == root + "." + extension
* Return NULL if there is no file extension and don't set *root in this case.
*/
static bstr split_ext(bstr path, bstr *root)
{
mp_assert(path);
const char *bn = mp_basename(path);
bstr basename = mp_basename_bstr(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, ".");
basename = bstr_splice(basename, bstrspn(basename, "."), basename.len);

const char *split = strrchr(bn, '.');
if (!split || !split[1])
return NULL;
int dot_pos = bstrrchr(basename, '.');
if (dot_pos < 0 || dot_pos == basename.len - 1)
return bstr0(NULL);
bstr ext = bstr_splice(basename, dot_pos + 1, basename.len);
if (root)
*root = (bstr){(char *)path, split - path};
return (char *)split + 1;
*root = (bstr){path.start, ext.start - 1 - path.start };
return ext;
}

bstr bstr_strip_ext(bstr path)
{
bstr root = {0};
split_ext(path, &root);
return root.len ? root : path;
}

char *mp_strip_ext(void *talloc_ctx, const char *s)
bstr bstr_get_ext(bstr path)
{
bstr root;
return mp_splitext(s, &root) ? bstrto0(talloc_ctx, root) : talloc_strdup(talloc_ctx, s);
return split_ext(path, NULL);
}

bool mp_path_is_absolute(struct bstr path)
Expand Down
12 changes: 3 additions & 9 deletions misc/path_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,10 @@
// Return pointer to filename part of path

const char *mp_basename(const char *path);
bstr mp_basename_bstr(bstr 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);

// This is a shorthand to remove the extension
char *mp_strip_ext(void *talloc_ctx, const char *s);
bstr bstr_strip_ext(bstr path);
bstr bstr_get_ext(bstr path);

/* Return struct bstr referencing directory part of path, or if that
* would be empty, ".".
Expand Down
2 changes: 1 addition & 1 deletion player/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +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;
f = mp_strip_ext(filename, f);
f = bstrto0(filename, bstr_strip_ext(bstr0(f)));
}
}
int r = m_property_strdup_ro(action, arg, f);
Expand Down
2 changes: 1 addition & 1 deletion player/configfiles.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void mp_load_auto_profiles(struct MPContext *mpctx)
mp_auto_load_profile(mpctx, "protocol",
mp_split_proto(bstr0(mpctx->filename), NULL));
mp_auto_load_profile(mpctx, "extension",
bstr0(mp_splitext(mpctx->filename, NULL)));
bstr_get_ext(bstr0(mpctx->filename)));

mp_load_per_file_config(mpctx);
}
Expand Down
5 changes: 2 additions & 3 deletions player/screenshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static char *create_fname(struct MPContext *mpctx, char *template,
name = mp_url_unescape(res, name);

if (fmt == 'F')
name = mp_strip_ext(res, name);
name = bstrto0(res, bstr_strip_ext(bstr0(name)));
append_filename(&res, name);
break;
}
Expand Down Expand Up @@ -482,8 +482,7 @@ void cmd_screenshot_to_file(void *p)
int mode = cmd->args[1].v.i;
struct image_writer_opts opts = *mpctx->opts->screenshot_image_opts;

char *ext = mp_splitext(filename, NULL);
int format = image_writer_format_from_ext(ext);
int format = image_writer_format_from_ext(bstr_get_ext(bstr0(filename)));
if (format)
opts.format = format;
bool high_depth = image_writer_high_depth(&opts);
Expand Down
6 changes: 3 additions & 3 deletions player/scripting.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ static MP_THREAD_VOID script_thread(void *p)

static int64_t mp_load_script(struct MPContext *mpctx, const char *fname)
{
char *ext = mp_splitext(fname, NULL);
if (ext && strcasecmp(ext, "disable") == 0)
bstr ext = bstr_get_ext(bstr0(fname));
if (ext.len && bstrcasecmp(ext, bstr0("disable")) == 0)
return 0;

void *tmp = talloc_new(NULL);
Expand Down Expand Up @@ -144,7 +144,7 @@ static int64_t mp_load_script(struct MPContext *mpctx, const char *fname)
} else {
for (int n = 0; scripting_backends[n]; n++) {
const struct mp_scripting *b = scripting_backends[n];
if (ext && strcasecmp(ext, b->file_ext) == 0) {
if (ext.len && bstrcasecmp(ext, bstr0(b->file_ext)) == 0) {
backend = b;
break;
}
Expand Down
4 changes: 2 additions & 2 deletions video/image_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,10 @@ bool image_writer_flexible_csp(const struct image_writer_opts *opts)
|| opts->format == AV_CODEC_ID_PNG;
}

int image_writer_format_from_ext(const char *ext)
int image_writer_format_from_ext(bstr ext)
{
for (int n = 0; mp_image_writer_formats[n].name; n++) {
if (ext && strcmp(mp_image_writer_formats[n].name, ext) == 0)
if (ext.len && bstrcmp(bstr0(mp_image_writer_formats[n].name), ext) == 0)
return mp_image_writer_formats[n].value;
}
return 0;
Expand Down
2 changes: 1 addition & 1 deletion video/image_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ bool image_writer_high_depth(const struct image_writer_opts *opts);
bool image_writer_flexible_csp(const struct image_writer_opts *opts);

// Map file extension to format ID - return 0 (which is invalid) if unknown.
int image_writer_format_from_ext(const char *ext);
int image_writer_format_from_ext(bstr ext);

/*
* Save the given image under the given filename. The parameters csp and opts
Expand Down
4 changes: 1 addition & 3 deletions video/out/vo_gpu_next.c
Original file line number Diff line number Diff line change
Expand Up @@ -2438,9 +2438,7 @@ static void update_hook_opts(struct priv *p, char **opts, const char *shaderpath
return;

const char *basename = mp_basename(shaderpath);
struct bstr shadername;
if (!mp_splitext(basename, &shadername))
shadername = bstr0(basename);
struct bstr shadername = bstr_strip_ext(bstr0(basename));

for (int n = 0; opts[n * 2]; n++) {
struct bstr k = bstr0(opts[n * 2 + 0]);
Expand Down
Loading