Make it possible to restore from profiles by backing up the option
values before profile application. This is sort of like unapplying a
profile. Since there might be multiple ways to do this, a profile needs
to explicitly provide the "profile-restore" option, which specifies how
exactly this should be done.
This is a big mess. There is not natural way to do this. Profile
application is "destructive" and simply changes the values of the
options. Maybe one could argue that the option system should have
hierarchical "overlays" of profiles instead, where unset options will
use the value of the lower profiles. Options set interactively by the
user would be the top profile. Default values would be in the lowest
profile. You could unapply a profile by simply removing it from this
overlay stack.
But uh, let's not, so here's something stupid. It reuses some code used
for file local options to reduce code size. At least the overlay idea
would still be possible in theory, and could be added as another
profile-restore mode.
This is used by the following commit.
This is taken from a somewhat older proof-of-concept script. The basic
idea, and most of the implementation, is still the same. The way the
profiles are actually defined changed.
I still feel bad about this being a Lua script, and running user
expressions as Lua code in a vaguely defined environment, but I guess as
far as balance of effort/maintenance/results goes, this is fine.
It's a bit bloated (the Lua scripting state is at least 150KB or so in
total), so in order to enable this by default, I decided it should
unload itself by default if no auto-profiles are used. (And currently,
it does not actually rescan the profile list if a new config file is
loaded some time later, so the script would do nothing anyway if no auto
profiles were defined.)
This still requires defining inverse profiles for "unapplying" a
profile. Also this is still somewhat racy. Both will probably be
alleviated to some degree in the future.
All authors of the current code have agreed (as far as this commit
requires).
options.c/options.h will take more effort, because it contains all the
option declarations, and thus is touched extremely often.
m_option.c is technically still GPL, because of commit 2c82d5a1d8
(michael has agreed to LGPL, but only once the core of mpv is LGPL).
The geometry parsing code in m_option.c was originally by someone who
could not be reached. However, it was heavily rewritten anyway, and only
the syntax remains (i.e. not copyright-relevant).
parse_commandline.c contains a change by "adland" (commit 1d0ac71ae8),
who could not be reached - this this specific part is GPL only.
Fortunately, it matters only for DVD (and even then is more like a hack,
but whatever).
There are some other relevant changes, but they have all been reverted,
moved somewhere else, deleted, or replaced.
Application of options in the default section is "delayed" until the
whole config file is read in order to allow profile forward references.
This was run at the end of parsing a config file - but because of
"include" options, this means it's not always called at the end of the
main config file.
Use the recursion counter to prevent it from being processed after each
"include" option. This also gets rid of the resulting unintended
infinite recursion (which eventually stopped and failed loading the
config file) due to m_config_finish_default_profile() processing the
"include" option again.
Fixes#4024.
This works by first parsing a config file into the default profile, and
applying it once parsing the whole file is finished.
This won't work across config files (not even if you include other
config files via "include=file.conf").
The format doesn't change. Some details are different, though. For
example, it will now accept option values with spaces even if they're
not quoted. (I see no reason why the user should be forced to add
quotes.)
The code is now smaller and should be much easier to extend. It also
can load config from in-memory buffers, which might be helpful in the
future.
read_file() should eventually be replaced with stream_read_complete().
But since the latter function may access options under various
circumstances, and also needs access to the mpv_global struct, there
is a separate implementation for now.
...because everything is terrible.
strerror() is not documented as having to be thread-safe by POSIX and
C11. (Which is pretty much bullshit, because both mandate threads and
some form of thread-local storage - so there's no excuse why
implementation couldn't implement this in a thread-safe way. Especially
with C11 this is ridiculous, because there is no way to use threads and
convert error numbers to strings at the same time!)
Since we heavily use threads now, we should avoid unsafe functions like
strerror().
strerror_r() is in POSIX, but GNU/glibc deliberately fucks it up and
gives the function different semantics than the POSIX one. It's a bit of
work to convince this piece of shit to expose the POSIX standard
function, and not the messed up GNU one.
strerror_l() is also in POSIX, but only since the 2008 standard, and
thus is not widespread.
The solution is using avlibc (libavutil, by its official name), which
handles the unportable details for us, mostly. We avoid some pain.
Something like "char *s = ...; isdigit(s[0]);" triggers undefined
behavior, because char can be signed, and thus s[0] can be a negative
value. The is*() functions require unsigned char _or_ EOF. EOF is a
special value outside of unsigned char range, thus the argument to the
is*() functions can't be a char.
This undefined behavior can actually trigger crashes if the
implementation of these functions e.g. uses lookup tables, which are
then indexed with out-of-range values.
Replace all <ctype.h> uses with our own custom mp_is*() functions added
with misc/ctype.h. As a bonus, these functions are locale-independent.
(Although currently, we _require_ C locale for other reasons.)
Often, user configs set options that are not suitable for encoding.
Usually, playback and encoding are pretty different things, so it makes
sense to keep them strictly separate. There are several possible
solutions. The approach taken by this commit is to basically ignore the
default config settings, and switch to an [encoding] config profile
section instead. This also makes it impossible to have --o in a config
file, because --o enables encode mode.
See github issue #727 for discussion.
Since m_option.h and options.h are extremely often included, a lot of
files have to be changed.
Moving path.c/h to options/ is a bit questionable, but since this is
mainly about access to config files (which are also handled in
options/), it's probably ok.