public static bool AssociatesWith(this RantDictionaryEntry a, RantDictionaryEntry b) { if (a == null || b == null) return false; bool aNoneRequired = !a.GetRequiredClasses().Any(); bool bNoneRequired = !b.GetRequiredClasses().Any(); if (aNoneRequired && bNoneRequired) return true; // If both have no required classes, pass. // One or both have required classes. // Remove B optionals from A required. var aRequired = a.GetRequiredClasses().Except(b.GetOptionalClasses()); // Remove A optionals from B required. var bRequired = b.GetRequiredClasses().Except(a.GetOptionalClasses()); // Both should be either empty, or have exactly the same classes. return !aRequired.Except(bRequired).Any() && aRequired.Any() == bRequired.Any(); }
public static bool AssociatesWith(this RantDictionaryEntry a, RantDictionaryEntry b) { if (a == null || b == null) { return(false); } bool aNoneRequired = !a.GetRequiredClasses().Any(); bool bNoneRequired = !b.GetRequiredClasses().Any(); if (aNoneRequired && bNoneRequired) { return(true); // If both have no required classes, pass. } // One or both have required classes. // Remove B optionals from A required. var aRequired = a.GetRequiredClasses().Except(b.GetOptionalClasses()); // Remove A optionals from B required. var bRequired = b.GetRequiredClasses().Except(a.GetOptionalClasses()); // Both should be either empty, or have exactly the same classes. return(!aRequired.Except(bRequired).Any() && aRequired.Any() == bRequired.Any()); }
public static bool DivergesFrom(this RantDictionaryEntry a, RantDictionaryEntry b) { if (a == null || b == null) { return(false); } bool aNoneRequired = !a.GetRequiredClasses().Any(); bool bNoneRequired = !b.GetRequiredClasses().Any(); if (aNoneRequired && bNoneRequired) { return(true); // If both have no required classes, pass. } // One or both have required classes. // Remove B optionals from A required. var aRequired = a.GetRequiredClasses().Except(b.GetOptionalClasses()); // Remove A optionals from B required. var bRequired = b.GetRequiredClasses().Except(a.GetOptionalClasses()); // Both should be either empty, or differ by at least one class. return(aRequired.Except(bRequired).Any() || bRequired.Except(aRequired).Any()); }
public static bool RelatesWith(this RantDictionaryEntry a, RantDictionaryEntry b) { if (a == null || b == null) { return(false); } bool aNoneRequired = !a.GetRequiredClasses().Any(); bool bNoneRequired = !b.GetRequiredClasses().Any(); if (aNoneRequired && bNoneRequired) { return(true); // If both have no required classes, pass. } // One or both have required classes. // Remove B optionals from A required. var aRequired = a.GetRequiredClasses().Except(b.GetOptionalClasses()); // Remove A optionals from B required. var bRequired = b.GetRequiredClasses().Except(a.GetOptionalClasses()); // Both should share at least one class. return(aRequired.Intersect(bRequired).Any()); }
// Returns the classes of an object, but optional classes are postfixed with ? private static IEnumerable <string> GetClassesForExport(RantDictionaryEntry entry) { return(entry.GetRequiredClasses().Concat(entry.GetOptionalClasses().Select(x => x + "?"))); }
public static bool RelatesWith(this RantDictionaryEntry a, RantDictionaryEntry b) { if (a == null || b == null) return false; bool aNoneRequired = !a.GetRequiredClasses().Any(); bool bNoneRequired = !b.GetRequiredClasses().Any(); if (aNoneRequired && bNoneRequired) return true; // If both have no required classes, pass. // One or both have required classes. // Remove B optionals from A required. var aRequired = a.GetRequiredClasses().Except(b.GetOptionalClasses()); // Remove A optionals from B required. var bRequired = b.GetRequiredClasses().Except(a.GetOptionalClasses()); // Both should share at least one class. return aRequired.Intersect(bRequired).Any(); }
public static bool DivergesFrom(this RantDictionaryEntry a, RantDictionaryEntry b) { if (a == null || b == null) return false; bool aNoneRequired = !a.GetRequiredClasses().Any(); bool bNoneRequired = !b.GetRequiredClasses().Any(); if (aNoneRequired && bNoneRequired) return true; // If both have no required classes, pass. // One or both have required classes. // Remove B optionals from A required. var aRequired = a.GetRequiredClasses().Except(b.GetOptionalClasses()); // Remove A optionals from B required. var bRequired = b.GetRequiredClasses().Except(a.GetOptionalClasses()); // Both should be either empty, or differ by at least one class. return aRequired.Except(bRequired).Any() || bRequired.Except(aRequired).Any(); }
public static void ReadTerms(string origin, string str, int len, int line, ref int i, RantDictionaryTable table, RantDictionaryEntry activeTemplate, Dictionary <string, RantDictionaryEntry> templates, out RantDictionaryEntry result) { SkipSpace(str, len, ref i); int t = 0; var terms = new RantDictionaryTerm[table.TermsPerEntry]; int split = -1; char c = '\0'; var buffer = new StringBuilder(); var white = new StringBuilder(); while (i < len) { switch (c = str[i++]) { // Inline comment case '#': goto done; // Phrasal split operator case '+': if (split > -1) { throw new RantTableLoadException(origin, line, i, "err-table-multiple-splits"); } white.Length = 0; split = buffer.Length; SkipSpace(str, len, ref i); break; // Term reference case '[': { SkipSpace(str, len, ref i); if (i >= len) { throw new RantTableLoadException(origin, line, i, "err-table-incomplete-term-reference"); } int start = i; if (white.Length > 0) { buffer.Append(white); white.Length = 0; } switch (str[i++]) { // Current term from active template case ']': if (t == -1) { throw new RantTableLoadException(origin, line, start + 1, "err-table-no-template"); } buffer.Append(activeTemplate[t].Value); break; // Custom term from active template case '.': { if (activeTemplate == null) { throw new RantTableLoadException(origin, line, start + 1, "err-table-no-template"); } while (i < len && IsValidSubtypeChar(str[i])) { i++; // Read subtype name } if (str[i] != ']') { throw new RantTableLoadException(origin, line, i, "err-table-incomplete-term-reference"); } string subName = str.Substring(start + 1, i - start - 1); if (subName.Length == 0) { throw new RantTableLoadException(origin, line, start + 1, "err-table-empty-subtype-reference"); } int templateSubIndex = table.GetSubtypeIndex(subName); if (templateSubIndex == -1) { throw new RantTableLoadException(origin, line, start + 1, "err-table-nonexistent-subtype", subName); } // Add term value to buffer buffer.Append(activeTemplate[templateSubIndex].Value); i++; // Skip past closing bracket break; } // It is probably a reference to another entry, let's see. default: { while (i < len && IsValidSubtypeChar(str[i]) || str[i] == '.') { i++; } if (str[i] != ']') { throw new RantTableLoadException(origin, line, i, "err-table-incomplete-term-reference"); } var id = str.Substring(start, i - start).Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); switch (id.Length) { // It's just a template ID. case 1: { if (!templates.TryGetValue(id[0], out RantDictionaryEntry entry)) { throw new RantTableLoadException(origin, line, start + 1, "err-table-entry-not-found"); } // Append term value to buffer buffer.Append(entry[t].Value); break; } // Template ID and custom subtype case 2: { if (!templates.TryGetValue(id[0], out RantDictionaryEntry entry)) { throw new RantTableLoadException(origin, line, start + 1, "err-table-entry-not-found"); } int templateSubIndex = table.GetSubtypeIndex(id[1]); if (templateSubIndex == -1 || templateSubIndex >= table.TermsPerEntry) { throw new RantTableLoadException(origin, line, start + 1, "err-table-nonexistent-subtype", id[1]); } buffer.Append(entry[templateSubIndex].Value); break; } // ??? default: throw new RantTableLoadException(origin, line, start + 1, "err-table-invalid-term-reference"); } i++; // Skip past closing bracket break; } } break; } case '\\': { if (white.Length > 0) { buffer.Append(white); white.Length = 0; } switch (c = str[i++]) { case 'n': buffer.Append('\n'); continue; case 'r': buffer.Append('\r'); continue; case 't': buffer.Append('\t'); continue; case 'v': buffer.Append('\v'); continue; case 'f': buffer.Append('\f'); continue; case 'b': buffer.Append('\b'); continue; case 's': buffer.Append(' '); continue; case 'u': { if (i + 4 > len) { throw new RantTableLoadException(origin, line, i + 1, "err-table-incomplete-escape"); } if (!ushort.TryParse(str.Substring(i, 4), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out ushort codePoint)) { throw new RantTableLoadException(origin, line, i + 1, "err-table-unrecognized-codepoint"); } buffer.Append((char)codePoint); i += 4; continue; } case 'U': { if (i + 8 > len) { throw new RantTableLoadException(origin, line, i + 1, "err-table-incomplete-escape"); } if (!Util.TryParseSurrogatePair(str.Substring(i, 8), out char high, out char low)) { throw new RantTableLoadException(origin, line, i + 1, "err-table-unrecognized-codepoint"); } buffer.Append(high).Append(low); i += 8; continue; } default: buffer.Append(c); continue; } continue; } case ',': if (t >= terms.Length) { throw new RantTableLoadException(origin, line, i, "err-table-too-many-terms", terms.Length, t); } terms[t++] = new RantDictionaryTerm(buffer.ToString(), split); buffer.Length = 0; white.Length = 0; split = -1; SkipSpace(str, len, ref i); break; default: if (char.IsWhiteSpace(c)) { white.Append(c); } else { if (white.Length > 0) { buffer.Append(white); white.Length = 0; } buffer.Append(c); } continue; } } done: if (t != terms.Length - 1) { throw new RantTableLoadException(origin, line, i, "err-table-too-few-terms", terms.Length, t + 1); } terms[t] = new RantDictionaryTerm(buffer.ToString()); result = new RantDictionaryEntry(terms); // Add classes from template if (activeTemplate != null) { foreach (string cl in activeTemplate.GetRequiredClasses()) { result.AddClass(cl, false); } foreach (string cl in activeTemplate.GetOptionalClasses()) { result.AddClass(cl, true); } } }
// Returns the classes of an object, but optional classes are postfixed with ? private static IEnumerable<string> GetClassesForExport(RantDictionaryEntry entry) { return entry.GetRequiredClasses().Concat(entry.GetOptionalClasses().Select(x => x + "?")); }