Regex matches now get merged into exact matches.

Also updated syntax doc to describe merging. Fixes #276.
This commit is contained in:
WrinklyNinja
2014-09-01 15:22:52 +01:00
parent 0997e3a931
commit 2d3efe66ea
3 changed files with 40 additions and 16 deletions
+18
View File
@@ -322,6 +322,24 @@ nav: 0
<tr><td><code>url</code><td>location list<td>&#x2717;<td>An unordered list of locations for this plugin. If the same version can be found at multiple locations, only one location should be recorded. This metadata is not currently used by LOOT.
<tr><td><code>dirty</code><td>dirty info list<td>&#x2717;<td>An unordered list of dirty info structures for this plugin.
</table>
<p><strong>Each plugin must have only one matching non-regex entry.</strong> If multiple non-regex entries exist with the same <code>name</code> value, all but the first will be ignored. A plugin may match any number of regex entries though, and their metadata will be merged, with later entries being merged into earlier entries as detailed in the table below. Merging only takes place if both entries have their <code>enabled</code> value set to <code>true</code> (which is the default if unspecified).
<table>
<thead>
<tr><th>Key Name<th>Merge Behaviour (merging B into A)
<tbody>
<tr><td><code>name</code><td>Not merged.
<tr><td><code>enabled</code><td>Replaced but must be `true` anyway.
<tr><td><code>priority</code><td>Replaced by B's value.
<tr><td><code>after</code><td>Merged. If A and B both contain an entry with the same <code>name</code> value, B's copy is skipped.
<tr><td><code>req</code><td>Merged. If A and B both contain an entry with the same <code>name</code> value, B's copy is skipped.
<tr><td><code>inc</code><td>Merged. If A and B both contain an entry with the same <code>name</code> value, B's copy is skipped.
<tr><td><code>msg</code><td>Merged. If A and B both contain an entry with the same content string (if there are multiple content strings, the first is checked), then B's copy is skipped.
<tr><td><code>tag</code><td>Merged. If A and B both contain an entry with the same <code>name</code> value, B's copy is skipped, unless one is suggesting the tag for addition and the other is suggesting it for removal, in which case both entries are kept.
<tr><td><code>url</code><td>Currently skipped by the parser, so neither A nor B will contain any entries anyway.
<tr><td><code>dirty</code><td>Merged. If A and B both contain an entry with the same <code>crc</code> value, B's copy is skipped.
</table>
<p>Example:
<code class="box">name: 'Oscuro''s_Oblivion_Overhaul.esm'
req:
+13 -11
View File
@@ -180,18 +180,24 @@ namespace loot {
return pluginList;
}
// Merges multiple matching regex entries if any are found.
Plugin MetadataList::FindPlugin(const Plugin& plugin) const {
Plugin match(plugin.Name());
auto it = plugins.find(plugin);
if (it != plugins.end())
return *it;
match = *it;
// Now we want to also match possibly multiple regex entries.
it = find(regexPlugins.begin(), regexPlugins.end(), plugin);
while (it != regexPlugins.end()) {
match.MergeMetadata(*it);
if (it != regexPlugins.end())
return *it;
else
return Plugin(plugin.Name());
it = find(++it, regexPlugins.end(), plugin);
}
return match;
}
void MetadataList::AddPlugin(const Plugin& plugin) {
@@ -201,6 +207,8 @@ namespace loot {
plugins.insert(plugin);
}
// Doesn't erase matching regex entries, because they might also
// be required for other plugins.
void MetadataList::ErasePlugin(const Plugin& plugin) {
auto it = plugins.find(plugin);
@@ -208,12 +216,6 @@ namespace loot {
plugins.erase(it);
return;
}
it = find(regexPlugins.begin(), regexPlugins.end(), plugin);
if (it != regexPlugins.end()) {
regexPlugins.erase(it);
}
}
// Masterlist member functions
+9 -5
View File
@@ -20,7 +20,7 @@
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<http://www.gnu.org/licenses/>.
*/
*/
#ifndef __LOOT_GAME__
#define __LOOT_GAME__
@@ -41,7 +41,6 @@
#include <yaml-cpp/yaml.h>
namespace loot {
class Game;
/* Each Game object should store the config details specific to that game.
@@ -52,7 +51,7 @@ namespace loot {
global message lists.
Each game should have functions to load this plugin and masterlist / userlist
data. Plugin data should be loaded as header-only and as full data.
*/
*/
class MetadataList {
public:
@@ -63,8 +62,13 @@ namespace loot {
bool operator == (const MetadataList& rhs) const; //Compares content.
std::list<Plugin> Plugins() const;
// Merges multiple matching regex entries if any are found.
Plugin FindPlugin(const Plugin& plugin) const;
void AddPlugin(const Plugin& plugin);
// Doesn't erase matching regex entries, because they might also
// be required for other plugins.
void ErasePlugin(const Plugin& plugin);
std::list<Message> messages;
@@ -96,8 +100,8 @@ namespace loot {
Game(const unsigned int baseGameCode, const std::string& lootFolder = "");
Game& SetDetails(const std::string& name, const std::string& masterFile,
const std::string& repositoryURL, const std::string& repositoryBranch,
const std::string& path, const std::string& registry);
const std::string& repositoryURL, const std::string& repositoryBranch,
const std::string& path, const std::string& registry);
Game& SetPath(const std::string& path); //Used by API.
Game& Init();