diff --git a/SabreTools.Filtering/Cleaner.cs b/SabreTools.Filtering/Cleaner.cs
index 5134bc2b..0d1df113 100644
--- a/SabreTools.Filtering/Cleaner.cs
+++ b/SabreTools.Filtering/Cleaner.cs
@@ -4,8 +4,10 @@ using System.Linq;
using System.Text.RegularExpressions;
using SabreTools.Core;
+using SabreTools.Core.Tools;
using SabreTools.DatFiles;
using SabreTools.DatItems;
+using SabreTools.Logging;
namespace SabreTools.Filtering
{
@@ -114,6 +116,15 @@ namespace SabreTools.Filtering
///
public bool Trim { get; set; }
+ #endregion
+
+ #region Logging
+
+ ///
+ /// Logging object
+ ///
+ private Logger logger = new Logger();
+
#endregion
#region Cleaning
@@ -331,6 +342,80 @@ namespace SabreTools.Filtering
#region Filtering
+ ///
+ /// Populate the filters objects using a set of key:value filters
+ ///
+ /// List of key:value where ~key/!key is negated
+ public void PopulateFromList(List filters)
+ {
+ // Instantiate the filters, if necessary
+ DatHeaderFilter ??= new DatHeaderFilter();
+ MachineFilter ??= new MachineFilter();
+ DatItemFilter ??= new DatItemFilter();
+
+ foreach (string filterPair in filters)
+ {
+ (string field, string value, bool negate) = ProcessFilterPair(filterPair);
+
+ // If we don't even have a possible filter pair
+ if (field == null && value == null)
+ continue;
+
+ // DatHeader fields
+ DatHeaderField datHeaderField = field.AsDatHeaderField();
+ if (datHeaderField != DatHeaderField.NULL)
+ {
+ DatHeaderFilter.SetFilter(datHeaderField, value, negate);
+ continue;
+ }
+
+ // Machine fields
+ MachineField machineField = field.AsMachineField();
+ if (machineField != MachineField.NULL)
+ {
+ MachineFilter.SetFilter(machineField, value, negate);
+ continue;
+ }
+
+ // DatItem fields
+ DatItemField datItemField = field.AsDatItemField();
+ if (datItemField != DatItemField.NULL)
+ {
+ DatItemFilter.SetFilter(datItemField, value, negate);
+ continue;
+ }
+
+ // If we didn't match anything, log an error
+ logger.Warning($"The value {field} did not match any known field names. Please check the wiki for more details on supported field names.");
+ }
+ }
+
+ ///
+ /// Split the parts of a filter statement
+ ///
+ /// key:value where ~key/!key is negated
+ private (string field, string value, bool negate) ProcessFilterPair(string filter)
+ {
+ // If we don't even have a possible filter pair
+ if (!filter.Contains(":"))
+ {
+ logger.Warning($"'{filter}` is not a valid filter string. Valid filter strings are of the form 'key:value'. Please refer to README.1ST or the help feature for more details.");
+ return (null, null, false);
+ }
+
+ string filterTrimmed = filter.Trim('"', ' ', '\t');
+ bool negate = filterTrimmed.StartsWith("!")
+ || filterTrimmed.StartsWith("~")
+ || filterTrimmed.StartsWith("not-");
+ filterTrimmed = filterTrimmed.TrimStart('!', '~');
+ filterTrimmed = filterTrimmed.StartsWith("not-") ? filterTrimmed[4..] : filterTrimmed;
+
+ string filterFieldString = filterTrimmed.Split(':')[0].ToLowerInvariant().Trim('"', ' ', '\t');
+ string filterValue = filterTrimmed[(filterFieldString.Length + 1)..].Trim('"', ' ', '\t');
+
+ return (filterFieldString, filterValue, negate);
+ }
+
///
/// Check to see if a DatItem passes the filters
///
diff --git a/SabreTools.Filtering/DatHeaderFilter.cs b/SabreTools.Filtering/DatHeaderFilter.cs
index 3dafc3b5..b242df24 100644
--- a/SabreTools.Filtering/DatHeaderFilter.cs
+++ b/SabreTools.Filtering/DatHeaderFilter.cs
@@ -25,25 +25,6 @@ namespace SabreTools.Filtering
#region Filter Population
- ///
- /// Populate the filters object using a set of key:value filters
- ///
- /// List of key:value where ~key/!key is negated
- public override void PopulateFromList(List filters)
- {
- foreach (string filterPair in filters)
- {
- (string field, string value, bool negate) = ProcessFilterPair(filterPair);
-
- // If we don't even have a possible filter pair
- if (field == null && value == null)
- continue;
-
- DatHeaderField filterField = field.AsDatHeaderField();
- SetFilter(filterField, value, negate);
- }
- }
-
///
/// Set multiple filters from key
///
diff --git a/SabreTools.Filtering/DatItemFilter.cs b/SabreTools.Filtering/DatItemFilter.cs
index 7c76fa45..998cc31e 100644
--- a/SabreTools.Filtering/DatItemFilter.cs
+++ b/SabreTools.Filtering/DatItemFilter.cs
@@ -208,25 +208,6 @@ namespace SabreTools.Filtering
#region Filter Population
- ///
- /// Populate the filters object using a set of key:value filters
- ///
- /// List of key:value where ~key/!key is negated
- public override void PopulateFromList(List filters)
- {
- foreach (string filterPair in filters)
- {
- (string field, string value, bool negate) = ProcessFilterPair(filterPair);
-
- // If we don't even have a possible filter pair
- if (field == null && value == null)
- continue;
-
- DatItemField filterField = field.AsDatItemField();
- SetFilter(filterField, value, negate);
- }
- }
-
///
/// Set multiple filters from key
///
diff --git a/SabreTools.Filtering/Filter.cs b/SabreTools.Filtering/Filter.cs
index 0294eeeb..f7ec3d38 100644
--- a/SabreTools.Filtering/Filter.cs
+++ b/SabreTools.Filtering/Filter.cs
@@ -33,12 +33,6 @@ namespace SabreTools.Filtering
#region Filter Population
- ///
- /// Populate the filters object using a set of key:value filters
- ///
- /// List of key:value where ~key/!key is negated
- public abstract void PopulateFromList(List filters);
-
///
/// Split the parts of a filter statement
///
diff --git a/SabreTools.Filtering/MachineFilter.cs b/SabreTools.Filtering/MachineFilter.cs
index 34f33b21..38639001 100644
--- a/SabreTools.Filtering/MachineFilter.cs
+++ b/SabreTools.Filtering/MachineFilter.cs
@@ -112,25 +112,6 @@ namespace SabreTools.Filtering
#region Filter Population
- ///
- /// Populate the filters object using a set of key:value filters
- ///
- /// List of key:value where ~key/!key is negated
- public override void PopulateFromList(List filters)
- {
- foreach (string filterPair in filters)
- {
- (string field, string value, bool negate) = ProcessFilterPair(filterPair);
-
- // If we don't even have a possible filter pair
- if (field == null && value == null)
- continue;
-
- MachineField filterField = field.AsMachineField();
- SetFilter(filterField, value, negate);
- }
- }
-
///
/// Set multiple filters from key
///
diff --git a/SabreTools/Features/BaseFeature.cs b/SabreTools/Features/BaseFeature.cs
index 1e74267e..5e0b914e 100644
--- a/SabreTools/Features/BaseFeature.cs
+++ b/SabreTools/Features/BaseFeature.cs
@@ -2698,9 +2698,7 @@ Some special strings that can be used:
// Populate filters
List filterPairs = GetList(features, FilterListValue);
- cleaner.DatHeaderFilter.PopulateFromList(filterPairs);
- cleaner.DatItemFilter.PopulateFromList(filterPairs);
- cleaner.MachineFilter.PopulateFromList(filterPairs);
+ cleaner.PopulateFromList(filterPairs);
// Include 'of" in game filters
cleaner.MachineFilter.IncludeOfInGame = GetBoolean(features, MatchOfTagsValue);