summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/m_config.c61
-rw-r--r--core/m_config.h26
-rw-r--r--core/m_option.h5
-rw-r--r--core/mplayer.c32
-rw-r--r--core/parser-cfg.c9
-rw-r--r--core/parser-cfg.h3
-rw-r--r--core/parser-mpcmd.c12
7 files changed, 67 insertions, 81 deletions
diff --git a/core/m_config.c b/core/m_config.c
index e63952e577..f362b43836 100644
--- a/core/m_config.c
+++ b/core/m_config.c
@@ -54,20 +54,21 @@ struct m_opt_backup {
void *backup;
};
-static int parse_include(struct m_config *config, struct bstr param, bool set)
+static int parse_include(struct m_config *config, struct bstr param, bool set,
+ int flags)
{
if (param.len == 0)
return M_OPT_MISSING_PARAM;
if (!set)
return 1;
char *filename = bstrdup0(NULL, param);
- config->includefunc(config, filename);
+ config->includefunc(config, filename, flags);
talloc_free(filename);
return 1;
}
static int parse_profile(struct m_config *config, const struct m_option *opt,
- struct bstr name, struct bstr param, bool set)
+ struct bstr name, struct bstr param, bool set, int flags)
{
if (!bstrcmp0(param, "help")) {
struct m_profile *p;
@@ -97,7 +98,7 @@ static int parse_profile(struct m_config *config, const struct m_option *opt,
list[i]);
r = M_OPT_INVALID;
} else if (set)
- m_config_set_profile(config, p);
+ m_config_set_profile(config, p, flags);
}
m_option_free(opt, &list);
return r;
@@ -182,8 +183,7 @@ static void add_options(struct m_config *config,
static int config_destroy(void *p)
{
struct m_config *config = p;
- if (config->file_local_mode)
- m_config_leave_file_local(config);
+ m_config_restore_backups(config);
for (struct m_config_option *copt = config->opts; copt; copt = copt->next)
m_option_free(copt->opt, copt->data);
return 0;
@@ -257,8 +257,6 @@ int m_config_initialize_obj(struct m_config *config, struct m_obj_desc *desc,
static void ensure_backup(struct m_config *config, struct m_config_option *co)
{
- if (!config->file_local_mode)
- return;
if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
return;
if (co->opt->flags & M_OPT_GLOBAL)
@@ -279,20 +277,8 @@ static void ensure_backup(struct m_config *config, struct m_config_option *co)
config->backup_opts = bc;
}
-void m_config_enter_file_local(struct m_config *config)
-{
- assert(!config->file_local_mode);
- config->file_local_mode = true;
- for (struct m_config_option *co = config->opts; co; co = co->next) {
- if (co->opt->flags & M_OPT_LOCAL)
- ensure_backup(config, co);
- }
-}
-
-void m_config_leave_file_local(struct m_config *config)
+void m_config_restore_backups(struct m_config *config)
{
- assert(config->file_local_mode);
- config->file_local_mode = false;
while (config->backup_opts) {
struct m_opt_backup *bc = config->backup_opts;
config->backup_opts = bc->next;
@@ -303,7 +289,7 @@ void m_config_leave_file_local(struct m_config *config)
}
}
-void m_config_mark_file_local(struct m_config *config, const char *opt)
+void m_config_backup_opt(struct m_config *config, const char *opt)
{
struct m_config_option *co = m_config_get_co(config, bstr0(opt));
if (co) {
@@ -313,7 +299,7 @@ void m_config_mark_file_local(struct m_config *config, const char *opt)
}
}
-void m_config_mark_all_file_local(struct m_config *config)
+void m_config_backup_all_opts(struct m_config *config)
{
for (struct m_config_option *co = config->opts; co; co = co->next)
ensure_backup(config, co);
@@ -346,8 +332,7 @@ static void add_negation_option(struct m_config *config,
*no_opt = (struct m_option) {
.name = talloc_asprintf(no_opt, "no-%s", opt->name),
.type = CONF_TYPE_STORE,
- .flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_LOCAL |
- M_OPT_PRE_PARSE),
+ .flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_PRE_PARSE),
.new = opt->new,
.p = opt->p,
.offset = opt->offset,
@@ -527,17 +512,21 @@ static int m_config_parse_option(struct m_config *config, struct bstr name,
BSTR_P(name));
return M_OPT_INVALID;
}
- if (config->file_local_mode && (co->opt->flags & M_OPT_GLOBAL)) {
- mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
- "The %.*s option is global and can't be set per-file.\n",
- BSTR_P(name));
- return M_OPT_INVALID;
+ if (flags & M_SETOPT_BACKUP) {
+ if (co->opt->flags & M_OPT_GLOBAL) {
+ mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
+ "The %.*s option is global and can't be set per-file.\n",
+ BSTR_P(name));
+ return M_OPT_INVALID;
+ }
+ if (set)
+ ensure_backup(config, co);
}
if (config->includefunc && bstr_equals0(name, "include"))
- return parse_include(config, param, set);
+ return parse_include(config, param, set, flags);
if (config->use_profiles && bstr_equals0(name, "profile"))
- return parse_profile(config, co->opt, name, param, set);
+ return parse_profile(config, co->opt, name, param, set, flags);
if (config->use_profiles && bstr_equals0(name, "show-profile"))
return show_profile(config, param);
if (bstr_equals0(name, "list-options"))
@@ -551,9 +540,6 @@ static int m_config_parse_option(struct m_config *config, struct bstr name,
return parse_subopts(config, co->name, prefix, param, flags);
}
- if (set)
- ensure_backup(config, co);
-
return m_option_parse(co->opt, name, param, set ? co->data : NULL);
}
@@ -763,7 +749,8 @@ int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
return 1;
}
-void m_config_set_profile(struct m_config *config, struct m_profile *p)
+void m_config_set_profile(struct m_config *config, struct m_profile *p,
+ int flags)
{
if (config->profile_depth > MAX_PROFILE_DEPTH) {
mp_tmsg(MSGT_CFGPARSER, MSGL_WARN,
@@ -775,7 +762,7 @@ void m_config_set_profile(struct m_config *config, struct m_profile *p)
m_config_set_option_ext(config,
bstr0(p->opts[2 * i]),
bstr0(p->opts[2 * i + 1]),
- M_SETOPT_FROM_CONFIG_FILE);
+ flags | M_SETOPT_FROM_CONFIG_FILE);
}
config->profile_depth--;
}
diff --git a/core/m_config.h b/core/m_config.h
index 09b4961a06..c2f88dfe65 100644
--- a/core/m_config.h
+++ b/core/m_config.h
@@ -54,11 +54,6 @@ typedef struct m_config {
// Registered options.
struct m_config_option *opts; // all options, even suboptions
- // When options are set (via m_config_set_option or m_config_set_profile),
- // back up the old value (unless it's already backed up). Used for restoring
- // global options when per-file options are set.
- bool file_local_mode;
-
// List of defined profiles.
struct m_profile *profiles;
// Depth when recursively including profiles.
@@ -67,7 +62,7 @@ typedef struct m_config {
struct m_opt_backup *backup_opts;
bool use_profiles;
- int (*includefunc)(struct m_config *conf, char *filename);
+ int (*includefunc)(struct m_config *conf, char *filename, int flags);
const void *optstruct_defaults;
size_t optstruct_size;
@@ -101,15 +96,22 @@ int m_config_set_obj_params(struct m_config *conf, char **args);
int m_config_initialize_obj(struct m_config *config, struct m_obj_desc *desc,
void **ppriv, char ***pargs);
-void m_config_enter_file_local(struct m_config *config);
-void m_config_leave_file_local(struct m_config *config);
-void m_config_mark_file_local(struct m_config *config, const char *opt);
-void m_config_mark_all_file_local(struct m_config *config);
+// Make sure the option is backed up. If it's already backed up, do nothing.
+// All backed up options can be restored with m_config_restore_backups().
+void m_config_backup_opt(struct m_config *config, const char *opt);
+
+// Call m_config_backup_opt() on all options.
+void m_config_backup_all_opts(struct m_config *config);
+
+// Restore all options backed up with m_config_backup_opt(), and delete the
+// backups afterwards.
+void m_config_restore_backups(struct m_config *config);
enum {
M_SETOPT_PRE_PARSE_ONLY = 1, // Silently ignore non-M_OPT_PRE_PARSE opt.
M_SETOPT_CHECK_ONLY = 2, // Don't set, just check name/value
M_SETOPT_FROM_CONFIG_FILE = 4, // Reject M_OPT_NOCFG opt. (print error)
+ M_SETOPT_BACKUP = 8, // Call m_config_backup_opt() before
};
// Set the named option to the given string.
@@ -204,8 +206,10 @@ int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
*
* \param config The config object.
* \param p The profile object.
+ * \param flags M_SETOPT_* bits
*/
-void m_config_set_profile(struct m_config *config, struct m_profile *p);
+void m_config_set_profile(struct m_config *config, struct m_profile *p,
+ int flags);
void *m_config_alloc_struct(void *talloc_parent,
const struct m_sub_options *subopts);
diff --git a/core/m_option.h b/core/m_option.h
index b237c4b243..89f3caa652 100644
--- a/core/m_option.h
+++ b/core/m_option.h
@@ -337,11 +337,6 @@ struct m_option {
// This option can't be set per-file when used with struct m_config.
#define M_OPT_GLOBAL (1 << 4)
-// This option is always considered per-file when used with struct m_config.
-// When playback of a file ends, the option value will be restored to the value
-// from before playback begin.
-#define M_OPT_LOCAL (1 << 5)
-
// The option should be set during command line pre-parsing
#define M_OPT_PRE_PARSE (1 << 6)
diff --git a/core/mplayer.c b/core/mplayer.c
index 2092a04f70..31b1e88efa 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -634,9 +634,9 @@ static void mk_config_dir(char *subdir)
talloc_free(tmp);
}
-static int cfg_include(struct m_config *conf, char *filename)
+static int cfg_include(struct m_config *conf, char *filename, int flags)
{
- return m_config_parse_config_file(conf, filename);
+ return m_config_parse_config_file(conf, filename, flags);
}
#define DEF_CONFIG "# Write your default config options here!\n\n\n"
@@ -648,7 +648,7 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
int conffile_fd;
if (!opts->load_config)
return true;
- if (!m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf") < 0)
+ if (!m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf", 0) < 0)
return false;
mk_config_dir(NULL);
if ((conffile = mp_find_user_config_file("config")) == NULL)
@@ -662,7 +662,7 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
write(conffile_fd, DEF_CONFIG, sizeof(DEF_CONFIG) - 1);
close(conffile_fd);
}
- if (m_config_parse_config_file(conf, conffile) < 0)
+ if (m_config_parse_config_file(conf, conffile, 0) < 0)
return false;
talloc_free(conffile);
}
@@ -688,7 +688,7 @@ static void load_per_protocol_config(m_config_t *conf, const char * const file)
if (p) {
mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
"Loading protocol-related profile '%s'\n", protocol);
- m_config_set_profile(conf, p);
+ m_config_set_profile(conf, p, M_SETOPT_BACKUP);
}
}
@@ -711,7 +711,7 @@ static void load_per_extension_config(m_config_t *conf, const char * const file)
if (p) {
mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
"Loading extension-related profile '%s'\n", extension);
- m_config_set_profile(conf, p);
+ m_config_set_profile(conf, p, M_SETOPT_BACKUP);
}
}
@@ -731,12 +731,12 @@ static void load_per_output_config(m_config_t *conf, char *cfg, char *out)
if (p) {
mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
"Loading extension-related profile '%s'\n", profile);
- m_config_set_profile(conf, p);
+ m_config_set_profile(conf, p, M_SETOPT_BACKUP);
}
}
/**
- * Tries to load a config file
+ * Tries to load a config file (in file local mode)
* @return 0 if file was not found, 1 otherwise
*/
static int try_load_config(m_config_t *conf, const char *file)
@@ -744,7 +744,7 @@ static int try_load_config(m_config_t *conf, const char *file)
if (!mp_path_exists(file))
return 0;
mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Loading config '%s'\n", file);
- m_config_parse_config_file(conf, file);
+ m_config_parse_config_file(conf, file, M_SETOPT_BACKUP);
return 1;
}
@@ -899,8 +899,10 @@ static void load_per_file_options(m_config_t *conf,
struct playlist_param *params,
int params_count)
{
- for (int n = 0; n < params_count; n++)
- m_config_set_option(conf, params[n].name, params[n].value);
+ for (int n = 0; n < params_count; n++) {
+ m_config_set_option_ext(conf, params[n].name, params[n].value,
+ M_SETOPT_BACKUP);
+ }
}
/* When demux performs a blocking operation (network connection or
@@ -4147,8 +4149,6 @@ static void play_current_file(struct MPContext *mpctx)
mpctx->add_osd_seek_info &= OSD_SEEK_INFO_EDITION;
- m_config_enter_file_local(mpctx->mconfig);
-
load_per_protocol_config(mpctx->mconfig, mpctx->filename);
load_per_extension_config(mpctx->mconfig, mpctx->filename);
load_per_file_config(mpctx->mconfig, mpctx->filename, opts->use_filedir_conf);
@@ -4170,9 +4170,9 @@ static void play_current_file(struct MPContext *mpctx)
for (int n = 0; opts->reset_options[n]; n++) {
const char *opt = opts->reset_options[n];
if (strcmp(opt, "all") == 0) {
- m_config_mark_all_file_local(mpctx->mconfig);
+ m_config_backup_all_opts(mpctx->mconfig);
} else {
- m_config_mark_file_local(mpctx->mconfig, opt);
+ m_config_backup_opt(mpctx->mconfig, opt);
}
}
}
@@ -4445,7 +4445,7 @@ terminate_playback: // don't jump here after ao/vo/getch initialization!
uninit_player(mpctx, uninitialize_parts);
// xxx handle this as INITIALIZED_CONFIG?
- m_config_leave_file_local(mpctx->mconfig);
+ m_config_restore_backups(mpctx->mconfig);
mpctx->filename = NULL;
talloc_free(mpctx->resolve_result);
diff --git a/core/parser-cfg.c b/core/parser-cfg.c
index 8f90d3f5e6..a69f4545d2 100644
--- a/core/parser-cfg.c
+++ b/core/parser-cfg.c
@@ -41,9 +41,11 @@ static int recursion_depth = 0;
/// Setup the \ref Config from a config file.
/** \param config The config object.
* \param conffile Path to the config file.
+ * \param flags M_SETOPT_* bits
* \return 1 on sucess, -1 on error, 0 if file not accessible.
*/
-int m_config_parse_config_file(m_config_t *config, const char *conffile)
+int m_config_parse_config_file(m_config_t *config, const char *conffile,
+ int flags)
{
#define PRINT_LINENUM mp_msg(MSGT_CFGPARSER, MSGL_ERR, "%s:%d: ", conffile, line_num)
#define MAX_LINE_LEN 10000
@@ -63,6 +65,8 @@ int m_config_parse_config_file(m_config_t *config, const char *conffile)
int errors = 0;
m_profile_t *profile = NULL;
+ flags = flags | M_SETOPT_FROM_CONFIG_FILE;
+
mp_msg(MSGT_CFGPARSER, MSGL_V, "Reading config file %s", conffile);
if (recursion_depth > MAX_RECURSION_DEPTH) {
@@ -219,8 +223,7 @@ int m_config_parse_config_file(m_config_t *config, const char *conffile)
if (profile) {
tmp = m_config_set_profile_option(config, profile, bopt, bparam);
} else {
- tmp = m_config_set_option_ext(config, bopt, bparam,
- M_SETOPT_FROM_CONFIG_FILE);
+ tmp = m_config_set_option_ext(config, bopt, bparam, flags);
}
if (tmp < 0) {
PRINT_LINENUM;
diff --git a/core/parser-cfg.h b/core/parser-cfg.h
index e083803edd..65a4b49496 100644
--- a/core/parser-cfg.h
+++ b/core/parser-cfg.h
@@ -21,6 +21,7 @@
#include "m_config.h"
-int m_config_parse_config_file(m_config_t* config, const char *conffile);
+int m_config_parse_config_file(m_config_t* config, const char *conffile,
+ int flags);
#endif /* MPLAYER_PARSER_CFG_H */
diff --git a/core/parser-mpcmd.c b/core/parser-mpcmd.c
index 3336fce027..d716fc4d28 100644
--- a/core/parser-mpcmd.c
+++ b/core/parser-mpcmd.c
@@ -131,16 +131,15 @@ int m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
struct playlist_param *local_params = 0;
assert(config != NULL);
- assert(!config->file_local_mode);
mode = GLOBAL;
struct parse_state p = {config, argc, argv};
while (split_opt(&p)) {
if (p.is_opt) {
+ int flags = mode == LOCAL ? M_SETOPT_BACKUP | M_SETOPT_CHECK_ONLY : 0;
int r;
- r = m_config_set_option_ext(config, p.arg, p.param,
- mode == LOCAL ? M_SETOPT_CHECK_ONLY : 0);
+ r = m_config_set_option_ext(config, p.arg, p.param, flags);
if (r <= M_OPT_EXIT) {
ret = r;
goto err_out;
@@ -161,8 +160,6 @@ int m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
goto err_out;
}
mode = LOCAL;
- // Needed for option checking.
- m_config_enter_file_local(config);
assert(!local_start);
local_start = files->last;
continue;
@@ -191,7 +188,7 @@ int m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
}
local_params_count = 0;
mode = GLOBAL;
- m_config_leave_file_local(config);
+ m_config_restore_backups(config);
local_start = NULL;
shuffle = false;
continue;
@@ -284,8 +281,7 @@ int m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
err_out:
talloc_free(local_params);
- if (config->file_local_mode)
- m_config_leave_file_local(config);
+ m_config_restore_backups(config);
return ret;
}