pub struct Table { /* private fields */ }Expand description
The whole database: the built-in rules followed by the rules of
ENV_VAR and then those of the file FILE_ENV_VAR names, in the
order they were declared, each with its Source.
A launcher builds the rules it sends with Table::new and
Table::push and writes them with to_string(), which is the value of
ENV_VAR; Table::with_builtin puts the built-in rules in front, as
compatdb.so does, to see what a process would get.
Implementations§
Source§impl Table
impl Table
Sourcepub fn resolve(
&self,
exe: &str,
version: &VersionInfo,
steam_app: Option<u32>,
) -> Resolution
pub fn resolve( &self, exe: &str, version: &VersionInfo, steam_app: Option<u32>, ) -> Resolution
Fold every matching rule into one Resolution. exe is the image
basename (see basename_of); version is the image’s version
resource, for the optional fingerprint constraints; steam_app is the
process’s Steam app id, if it has one (see steam_app), for the
rules that name one.
The rules fold in this order, each group in table order, which is
line order for the rules of ENV_VAR and then line order for those
of the file FILE_ENV_VAR names:
- built-in
*rules, those without a fingerprint first; - the caller’s
*rules, those without a fingerprint first; - built-in rules naming an executable, those without a fingerprint first;
- the caller’s rules naming an executable, those without a fingerprint first.
So a scalar field ends up holding the value of the last rule that
sets it. Whether a rule names an executable decides first, then where
it comes from, then whether it pins a fingerprint (see
Rule::specificity). The variable and the file are one place in
that order, so only table order tells them apart: a rule of the file
beats a rule of the variable of equal specificity, because it is
declared later, and a * rule of the file does not beat a rule of
the variable that names an executable. A launch-wide * rule of the
caller replaces a built-in default but not what a built-in rule for
one program sets, so that fix survives launch-wide settings, and a
rule of the caller for the program beats it, with or without a
fingerprint. The lists accumulate across every rule that matched, in
the same order. The exceptions are a
rule’s arguments_override, which replaces the arguments the rules
folded before it accumulated (the arguments of the rule itself and
of the rules folded after it append to it), a scalar set to
default (see Setting::Reset), and a dll_overrides entry with
the order default, which takes its modules out of the entries
before it.
The sort has to stay stable: rules of equal place in that order fold in table order.
A rule whose executable matches but whose fingerprint does not simply does not apply; nothing falls back to it, and the rules that do match still apply.
A rule for a Steam app id counts as naming an executable: it folds in
the same groups, in table order with the rules for a basename. Its
arguments_override is ignored (see Rule::arguments_override).
Source§impl Table
impl Table
Sourcepub fn builtin() -> Self
pub fn builtin() -> Self
The table of the built-in rules (builtin::rules), which
compatdb.so puts in front of the rules of ENV_VAR.
Sourcepub fn with_builtin(self) -> Self
pub fn with_builtin(self) -> Self
This table with the built-in rules in front of its own, as
compatdb.so builds its table.
Sourcepub fn append(&mut self, other: Self)
pub fn append(&mut self, other: Self)
Add the rules of other after these, with their sources, as
compatdb.so adds the rules of the file FILE_ENV_VAR names after
those of ENV_VAR.
A table that holds a file’s rules is for Table::resolve and
Table::preview. Display writes those rules too, so its text is
no value for ENV_VAR beside the file: they would fold twice.
Sourcepub fn push(&mut self, rule: Rule)
pub fn push(&mut self, rule: Rule)
Add rule after the others, as a rule of ENV_VAR on the line
after the last line of that variable in the table, which for a table
built with this method alone is its line in the value the table
writes.
Sourcepub fn sources(&self) -> &[Source]
pub fn sources(&self) -> &[Source]
Where each rule of Table::rules comes from, at the same index.
Sourcepub fn preview(&self, exe: &str, version: &VersionInfo) -> Resolution
pub fn preview(&self, exe: &str, version: &VersionInfo) -> Resolution
What a process with the image basename exe and the version
resource version would get from compatdb.so with this table in
ENV_VAR: the built-in rules followed by this table’s own (a
built-in rule in this table is left out, since the library has it
already), resolved, with Resolution::fold_derived_env done.
Which env entries apply also depends on the environment the process
starts with, which Resolution::env_steps takes.
The process has no Steam app id here, so a rule for one
(Exe::Steam) does not apply.
Sourcepub fn winedebug(&self) -> Vec<String>
pub fn winedebug(&self) -> Vec<String>
The WINEDEBUG entries the debug_channels of this table’s rules
stand for, in table order. A launcher joins them with , after its
own entries and starts Wine with the result, since Wine reads the
variable before compatdb.so loads.
An entry of a rule for an executable is scoped to it as
<exe>:<entry>, which is Wine’s own syntax: Wine compares the prefix
with the image file name ASCII-case-insensitively and knows nothing
of fingerprints, so the entry reaches every program of that name. An
entry of a rule with exe * is unscoped. Wine lets a later entry
win for the same channel.
An entry of a rule for a Steam app id is left out: Wine has no scope
for an app id, and without one the entry would reach every process.
Rule::set refuses such an entry.
Sourcepub fn duplicate_matchers(&self) -> Vec<(usize, usize)>
pub fn duplicate_matchers(&self) -> Vec<(usize, usize)>
Every pair of rules that matches exactly the same processes, by their index in the table. A duplicate can only be a mistake, so the launcher warns about it.
Plain wildcard rules (exe = * with no fingerprint) are left out: they
are defaults that are meant to stack, one per setting, so several of
them matching every process is not a mistake.
Source§impl Table
impl Table
Sourcepub fn parse_lenient(text: &str) -> (Self, Vec<Diagnostic>)
pub fn parse_lenient(text: &str) -> (Self, Vec<Diagnostic>)
Read the value of ENV_VAR the way compatdb.so does, which must
never abort a process: each rule gets its line as its Source, and
every problem is a Diagnostic (none when the text is clean).
- A field with an unknown key, a value its key does not take, no
=, escapes that are not UTF-8 or a NUL is left out, and the rest of its line still applies. - A line without an
exeis left out as a whole, since it matches no process. - A second field for a matcher or a scalar setting replaces the first one.
- A
%that two hex digits do not follow is kept as it is.
A first line that is a version header of the old format
(v=<digits>) is skipped without a diagnostic, so a launcher that
still writes one keeps working; it still counts as a line.
Sourcepub fn parse_file_lenient(text: &str) -> (Self, Vec<Diagnostic>)
pub fn parse_file_lenient(text: &str) -> (Self, Vec<Diagnostic>)
Read the text of the file FILE_ENV_VAR names the way
compatdb.so does: as Table::parse_lenient reads the value of
ENV_VAR, except that each rule’s Source is a
Source::FileLine and each Diagnostic names the file. Reading
the file is up to the caller.
Sourcepub fn parse_strict(text: &str) -> Result<Self, ParseError>
pub fn parse_strict(text: &str) -> Result<Self, ParseError>
Read the value of ENV_VAR, refusing any problem that
Table::parse_lenient would report. A table this gives back writes
itself (see Table’s Display) as text with blank lines and a
legacy header dropped and every word in lowercase.
§Errors
A ParseError with every diagnostic, when there is one.
Trait Implementations§
Source§impl Display for Table
impl Display for Table
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
The value of ENV_VAR: one record per rule, one per line, for
every rule that is not built in. The built-in rules are left out:
compatdb.so has them compiled in, and the same rules again from the
variable would fold after all of them.
Table::parse_strict reads a table this writes back as the same
table when the table’s own text is canonical: the table of
Table::new and Table::push, or of Table::parse_strict from
text this wrote.