Allow some options taking filenames to refer to mpv config dir

Add the mp_get_user_path() function, and make it expand special path
prefixes. Use it for some things in mpv which take filenames
(--input-config, --screenshot-template, opengl icc-profile suboption).

This allows accessing files in the mpv config dir without hardcoding the
config path by prefixing the path with ~~/. Details see manpage
additions.
This commit is contained in:
wm4 2013-12-14 19:50:00 +01:00
parent dcf9f77c58
commit 683d7e88e4
6 changed files with 73 additions and 10 deletions

View File

@ -285,6 +285,28 @@ It has the following format::
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
Paths
-----
Some care must be taken when passing arbitrary paths and filenames to mpv. For
example, paths starting with ``-`` will be interpreted as options. Likewise,
if a path contains the sequence ``://``, the string before that might be
interpreted as protocol prefix, even though ``://`` can be part of a legal
UNIX path. To avoid problems with arbitrary paths, you should be sure that
absolute paths passed to mpv start with ``/``, and relative paths with ``./``.
The name ``-`` itself is interpreted as stdin, and will cause mpv to disable
console controls. (Which makes it suitable for playing data piped to stdin.)
For paths passed to suboptions, the situation is further complicated by the
need to escape special characters. To work this around, the path can be
additionally wrapped in the ``%n%string_of_length_n`` syntax (see above).
Some mpv options interpret paths starting with ``~``. Currently, the prefix
``~~/`` expands to the mpv configuration directory (usually ``~/.mpv/``).
``~/`` expands to the user's home directory. (The trailing ``/`` is always
required.)
Per-File Options
----------------

View File

@ -2156,23 +2156,31 @@ static int parse_config(struct input_ctx *ictx, bool builtin, bstr data,
static int parse_config_file(struct input_ctx *ictx, char *file, bool warn)
{
int r = 0;
void *tmp = talloc_new(NULL);
stream_t *s = NULL;
file = mp_get_user_path(tmp, file);
if (!mp_path_exists(file)) {
MP_MSG(ictx, warn ? MSGL_ERR : MSGL_V,
"Input config file %s not found.\n", file);
return 0;
goto done;
}
stream_t *s = stream_open(file, NULL);
s = stream_open(file, NULL);
if (!s) {
MP_ERR(ictx, "Can't open input config file %s.\n", file);
return 0;
goto done;
}
bstr res = stream_read_complete(s, NULL, 1000000);
free_stream(s);
bstr data = stream_read_complete(s, tmp, 1000000);
MP_VERBOSE(ictx, "Parsing input config file %s\n", file);
int n_binds = parse_config(ictx, false, res, file, NULL);
talloc_free(res.start);
int n_binds = parse_config(ictx, false, data, file, NULL);
MP_VERBOSE(ictx, "Input config file %s parsed: %d binds\n", file, n_binds);
return 1;
r = 1;
done:
free_stream(s);
talloc_free(tmp);
return r;
}
// If name is NULL, return "default".

View File

@ -97,6 +97,28 @@ char *mp_find_global_config_file(const char *filename)
}
}
char *mp_get_user_path(void *talloc_ctx, const char *path)
{
if (!path)
return NULL;
bstr bpath = bstr0(path);
if (bstr_eatstart0(&bpath, "~")) {
// parse to "~" <prefix> "/" <rest>
bstr prefix, rest;
if (bstr_split_tok(bpath, "/", &prefix, &rest)) {
const char *rest0 = rest.start; // ok in this case
char *res = NULL;
if (bstr_equals0(prefix, "~"))
res = talloc_steal(talloc_ctx, mp_find_user_config_file(rest0));
if (bstr_equals0(prefix, ""))
res = mp_path_join(talloc_ctx, bstr0(getenv("HOME")), rest);
if (res)
return res;
}
}
return talloc_strdup(talloc_ctx, path);
}
char *mp_basename(const char *path)
{
char *s;

View File

@ -36,6 +36,11 @@ char *mp_find_global_config_file(const char *filename);
// Search for the input filename in the user configuration location.
char *mp_find_user_config_file(const char *filename);
// Normally returns a talloc_strdup'ed copy of the path, except for special
// paths starting with '~'. Used to allow the user explicitly reference a
// file from the user's home or mpv config directory.
char *mp_get_user_path(void *talloc_ctx, const char *path);
// Return pointer to filename part of path
char *mp_basename(const char *path);

View File

@ -233,7 +233,10 @@ static char *create_fname(struct MPContext *mpctx, char *template,
}
res = talloc_strdup_append(res, template);
return talloc_asprintf_append(res, ".%s", file_ext);
res = talloc_asprintf_append(res, ".%s", file_ext);
char *fname = mp_get_user_path(NULL, res);
talloc_free(res);
return fname;
error_exit:
talloc_free(res);

View File

@ -31,6 +31,7 @@
#include "mpvcore/bstr.h"
#include "mpvcore/mp_msg.h"
#include "mpvcore/m_option.h"
#include "mpvcore/path.h"
#include "gl_video.h"
#include "gl_lcms.h"
@ -90,11 +91,13 @@ static void lcms2_error_handler(cmsContext ctx, cmsUInt32Number code,
static struct bstr load_file(void *talloc_ctx, const char *filename)
{
struct bstr res = {0};
stream_t *s = stream_open(filename, NULL);
char *fname = mp_get_user_path(NULL, filename);
stream_t *s = stream_open(fname, NULL);
if (s) {
res = stream_read_complete(s, talloc_ctx, 1000000000);
free_stream(s);
}
talloc_free(fname);
return res;
}