From d054289f668499d6acea307f14c62d44d35b6840 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 11 Dec 2014 01:04:15 +0100 Subject: options: add slightly more sophistcated mechanism for option deprecation --- options/m_config.c | 126 ++++++++++++-------------------------------- options/m_config.h | 1 + options/m_option.c | 8 +++ options/m_option.h | 13 +++++ options/options.c | 73 +++++++++++++++++++++++++ options/parse_commandline.c | 3 ++ 6 files changed, 132 insertions(+), 92 deletions(-) diff --git a/options/m_config.c b/options/m_config.c index 852d4c194c..370fe09f32 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -39,8 +39,6 @@ static const union m_option_value default_value; -static const char *const replaced_opts; - // Profiles allow to predefine some sets of options that can then // be applied later on with the internal -profile option. #define MAX_PROFILE_DEPTH 20 @@ -374,6 +372,10 @@ static void m_config_add_option(struct m_config *config, .name = arg->name, }; + if (co.opt->type == &m_option_type_alias || + co.opt->type == &m_option_type_removed) + co.is_generated = true; + if (arg->offset >= 0) { if (optstruct) co.data = (char *)optstruct + arg->offset; @@ -437,17 +439,44 @@ static void m_config_add_option(struct m_config *config, struct m_config_option *m_config_get_co(const struct m_config *config, struct bstr name) { - + const char *prefix = config->is_toplevel ? "--" : ""; for (int n = 0; n < config->num_opts; n++) { struct m_config_option *co = &config->opts[n]; struct bstr coname = bstr0(co->name); + bool matches = false; if ((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && bstr_endswith0(coname, "*")) { coname.len--; if (bstrcmp(bstr_splice(name, 0, coname.len), coname) == 0) - return co; + matches = true; } else if (bstrcmp(coname, name) == 0) + matches = true; + if (matches) { + if (co->opt->type == &m_option_type_alias) { + const char *new = (const char *)co->opt->priv; + if (!co->warning_was_printed) { + MP_WARN(config, "Warning: option %s%s was replaced with " + "%s%s and might be removed in the future.\n", + prefix, co->name, prefix, new); + co->warning_was_printed = true; + } + return m_config_get_co(config, bstr0(new)); + } else if (co->opt->type == &m_option_type_removed) { + if (!co->warning_was_printed) { + char *msg = co->opt->priv; + if (msg) { + MP_FATAL(config, "Option %s%s was removed: %s\n", + prefix, co->name, msg); + } else { + MP_FATAL(config, "Option %s%s was removed.\n", + prefix, co->name); + } + co->warning_was_printed = true; + } + return NULL; + } return co; + } } return NULL; } @@ -550,18 +579,8 @@ static int m_config_parse_option(struct m_config *config, struct bstr name, assert(name.len != 0); struct m_config_option *co = m_config_get_co(config, name); - if (!co) { - char s[80]; - snprintf(s, sizeof(s), "|%.*s#", BSTR_P(name)); - char *msg = strstr(replaced_opts, s); - if (msg) { - msg += strlen(s); - char *end = strchr(msg, '|'); - MP_FATAL(config, "The --%.*s option was renamed or replaced: %.*s\n", - BSTR_P(name), (int)(end - msg), msg); - } + if (!co) return M_OPT_UNKNOWN; - } // This is the only mandatory function assert(co->opt->type->parse); @@ -919,80 +938,3 @@ struct m_config *m_config_dup(void *talloc_ctx, struct m_config *config) } return new; } - -// This is used for printing error messages on unknown options. -static const char *const replaced_opts = - "|a52drc#--ad-lavc-ac3drc=level" - "|afm#--ad" - "|aspect#--video-aspect" - "|ass-bottom-margin#--vf=sub=bottom:top" - "|ass#--sub-ass" - "|audiofile#--audio-file" - "|benchmark#--untimed (no stats)" - "|capture#--stream-capture=" - "|channels#--audio-channels (changed semantics)" - "|cursor-autohide-delay#--cursor-autohide" - "|delay#--audio-delay" - "|dumpstream#--stream-dump=" - "|dvdangle#--dvd-angle" - "|endpos#--length" - "|font#--osd-font" - "|forcedsubsonly#--sub-forced-only" - "|format#--audio-format" - "|hardframedrop#--framedrop=hard" - "|identify#removed; use TOOLS/mpv_identify.sh" - "|lavdopts#--vd-lavc-..." - "|lavfdopts#--demuxer-lavf-..." - "|lircconf#--input-lirc-conf" - "|mixer-channel#AO suboptions (alsa, oss)" - "|mixer#AO suboptions (alsa, oss)" - "|mouse-movements#--input-cursor" - "|msgcolor#--msg-color" - "|msglevel#--msg-level (changed semantics)" - "|msgmodule#--msg-module" - "|name#--x11-name" - "|noar#--no-input-appleremote" - "|noautosub#--no-sub-auto" - "|noconsolecontrols#--no-input-terminal" - "|nojoystick#--no-input-joystick" - "|nosound#--no-audio" - "|osdlevel#--osd-level" - "|panscanrange#--video-zoom, --video-pan-x/y" - "|playing-msg#--term-playing-msg" - "|pp#'--vf=pp=[...]'" - "|pphelp#--vf=pp:help" - "|rawaudio#--demuxer-rawaudio-..." - "|rawvideo#--demuxer-rawvideo-..." - "|spugauss#--sub-gauss" - "|srate#--audio-samplerate" - "|ss#--start" - "|stop-xscreensaver#--stop-screensaver" - "|sub-fuzziness#--sub-auto" - "|sub#--sub-file" - "|subcp#--sub-codepage" - "|subdelay#--sub-delay" - "|subfile#--sub" - "|subfont-text-scale#--sub-scale" - "|subfont#--sub-text-font" - "|subfps#--sub-fps" - "|subpos#--sub-pos" - "|tvscan#--tv-scan" - "|use-filename-title#--title='${filename}'" - "|vc#--vd=..., --hwdec=..." - "|vobsub#--sub (pass the .idx file)" - "|xineramascreen#--screen (different values)" - "|xy#--autofit" - "|zoom#Inverse available as ``--video-unscaled" - "|media-keys#--input-media-keys" - "|lirc#--input-lirc" - "|right-alt-gr#--input-right-alt-gr" - "|autosub#--sub-auto" - "|autosub-match#--sub-auto" - "|status-msg#--term-status-msg" - "|idx#--index" - "|forceidx#--index" - "|cache-pause-below#for 'no', use --no-cache-pause" - "|no-cache-pause-below#--no-cache-pause" - "|volstep#edit input.conf directly instead" - "|" -; diff --git a/options/m_config.h b/options/m_config.h index 2a27dc69a6..9993909e41 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -40,6 +40,7 @@ struct mp_log; struct m_config_option { bool is_generated : 1; // Automatically added ("no-" options) bool is_set_from_cmdline : 1; // Set by user from command line + bool warning_was_printed : 1; const char *name; // Full name (ie option-subopt) const struct m_option *opt; // Option description void *data; // Raw value of the option diff --git a/options/m_option.c b/options/m_option.c index 36470c792d..f59ce6a47c 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -3181,3 +3181,11 @@ const m_option_type_t m_option_type_node = { .set = node_set, .get = node_get, }; + +// Special-cased by m_config.c. +const m_option_type_t m_option_type_alias = { + .name = "alias", +}; +const m_option_type_t m_option_type_removed = { + .name = "removed", +}; diff --git a/options/m_option.h b/options/m_option.h index 41b1d9ec56..c05e2d760c 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -65,6 +65,10 @@ extern const m_option_type_t m_option_type_size_box; extern const m_option_type_t m_option_type_chmap; extern const m_option_type_t m_option_type_node; +// Used internally by m_config.c +extern const m_option_type_t m_option_type_alias; +extern const m_option_type_t m_option_type_removed; + // Callback used by m_option_type_print_fn options. typedef void (*m_opt_print_fn)(struct mp_log *log); @@ -679,4 +683,13 @@ extern const char m_option_path_separator; .type = &m_option_type_subconfig, \ .priv = (void*)&subconf) +// If "--name" was removed, but "--newname" has the same semantics. +// It will be redirected, and a warning will be printed on first use. +#define OPT_REPLACED(optname, newname) \ + {.name = optname, .type = &m_option_type_alias, .priv = newname, .offset = -1} + +// "--name" doesn't exist, but inform the user about a replacement with msg. +#define OPT_REMOVED(optname, msg) \ + {.name = optname, .type = &m_option_type_removed, .priv = msg, .offset = -1} + #endif /* MPLAYER_M_OPTION_H */ diff --git a/options/options.c b/options/options.c index e4e050af5f..375414b2ff 100644 --- a/options/options.c +++ b/options/options.c @@ -570,6 +570,79 @@ const m_option_t mp_opts[] = { OPT_FLAG("slave-broken", slave_mode, CONF_GLOBAL), + OPT_REMOVED("a52drc", "use --ad-lavc-ac3drc=level"), + OPT_REMOVED("afm", "use --ad=..."), + OPT_REPLACED("aspect", "video-aspect"), + OPT_REMOVED("ass-bottom-margin", "use --vf=sub=bottom:top"), + OPT_REPLACED("ass", "sub-ass"), + OPT_REPLACED("audiofile", "audio-file"), + OPT_REMOVED("benchmark", "use --untimed (no stats)"), + OPT_REMOVED("capture", "use --stream-capture="), + OPT_REMOVED("channels", "use --audio-channels (changed semantics)"), + OPT_REPLACED("cursor-autohide-delay", "cursor-autohide"), + OPT_REPLACED("delay", "audio-delay"), + OPT_REMOVED("dumpstream", "use --stream-dump="), + OPT_REPLACED("dvdangle", "dvd-angle"), + OPT_REPLACED("endpos", "length"), + OPT_REPLACED("font", "osd-font"), + OPT_REPLACED("forcedsubsonly", "sub-forced-only"), + OPT_REPLACED("format", "audio-format"), + OPT_REMOVED("hardframedrop", NULL), + OPT_REMOVED("identify", "use TOOLS/mpv_identify.sh"), + OPT_REMOVED("lavdopts", "use --vd-lavc-..."), + OPT_REMOVED("lavfdopts", "use --demuxer-lavf-..."), + OPT_REPLACED("lircconf", "input-lirc-conf"), + OPT_REMOVED("mixer-channel", "use AO suboptions (alsa, oss)"), + OPT_REMOVED("mixer", "use AO suboptions (alsa, oss)"), + OPT_REPLACED("mouse-movements", "input-cursor"), + OPT_REPLACED("msgcolor", "msg-color"), + OPT_REMOVED("msglevel", "use --msg-level (changed semantics)"), + OPT_REPLACED("msgmodule", "msg-module"), + OPT_REPLACED("name", "x11-name"), + OPT_REPLACED("noar", "no-input-appleremote"), + OPT_REPLACED("noautosub", "no-sub-auto"), + OPT_REPLACED("noconsolecontrols", "no-input-terminal"), + OPT_REPLACED("nojoystick", "no-input-joystick"), + OPT_REPLACED("nosound", "no-audio"), + OPT_REPLACED("osdlevel", "osd-level"), + OPT_REMOVED("panscanrange", "use --video-zoom, --video-pan-x/y"), + OPT_REPLACED("playing-msg", "term-playing-msg"), + OPT_REMOVED("pp", NULL), + OPT_REMOVED("pphelp", NULL), + OPT_REMOVED("rawaudio", "use --demuxer-rawaudio-..."), + OPT_REMOVED("rawvideo", "use --demuxer-rawvideo-..."), + OPT_REPLACED("spugauss", "sub-gauss"), + OPT_REPLACED("srate", "audio-samplerate"), + OPT_REPLACED("ss", "start"), + OPT_REPLACED("stop-xscreensaver", "stop-screensaver"), + OPT_REPLACED("sub-fuzziness", "sub-auto"), + OPT_REPLACED("sub", "sub-file"), + OPT_REPLACED("subcp", "sub-codepage"), + OPT_REPLACED("subdelay", "sub-delay"), + OPT_REPLACED("subfile", "sub"), + OPT_REPLACED("subfont-text-scale", "sub-scale"), + OPT_REPLACED("subfont", "sub-text-font"), + OPT_REPLACED("subfps", "sub-fps"), + OPT_REPLACED("subpos", "sub-pos"), + OPT_REPLACED("tvscan", "tv-scan"), + OPT_REMOVED("use-filename-title", "use --title='${filename}'"), + OPT_REMOVED("vc", "use --vd=..., --hwdec=..."), + OPT_REMOVED("vobsub", "use --sub-file (pass the .idx file)"), + OPT_REMOVED("xineramascreen", "use --screen (different values)"), + OPT_REMOVED("xy", "use --autofit"), + OPT_REMOVED("zoom", "Inverse available as ``--video-unscaled"), + OPT_REPLACED("media-keys", "input-media-keys"), + OPT_REPLACED("lirc", "input-lirc"), + OPT_REPLACED("right-alt-gr", "input-right-alt-gr"), + OPT_REPLACED("autosub", "sub-auto"), + OPT_REPLACED("autosub-match", "sub-auto"), + OPT_REPLACED("status-msg", "term-status-msg"), + OPT_REPLACED("idx", "index"), + OPT_REPLACED("forceidx", "index"), + OPT_REMOVED("cache-pause-below", "for 'no', use --no-cache-pause"), + OPT_REMOVED("no-cache-pause-below", "use --no-cache-pause"), + OPT_REMOVED("volstep", "edit input.conf directly instead"), + {0} }; diff --git a/options/parse_commandline.c b/options/parse_commandline.c index f82706a52a..424b8fc0c3 100644 --- a/options/parse_commandline.c +++ b/options/parse_commandline.c @@ -302,4 +302,7 @@ void m_config_preparse_command_line(m_config_t *config, struct mpv_global *globa } mp_msg_mute(global, false); + + for (int n = 0; n < config->num_opts; n++) + config->opts[n].warning_was_printed = false; } -- cgit v1.2.3