예제 #1
0
        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();
        }
예제 #2
0
        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());
        }
예제 #3
0
        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());
        }
예제 #4
0
        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());
        }
예제 #5
0
 // 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 + "?")));
 }
예제 #6
0
        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();
        }
예제 #7
0
        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();
        }
예제 #8
0
            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 + "?"));
 }