[Fontconfig] fontconfig: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Dec 17 05:12:16 UTC 2020


 src/fccfg.c                 |   16 ++-
 test/Makefile.am            |    4 
 test/meson.build            |    1 
 test/test-family-matching.c |  228 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 248 insertions(+), 1 deletion(-)

New commits:
commit df29933e1a06b7aa7af229bd7cd03c62d957f15f
Author: Szunti <Szunti at users.noreply.github.com>
Date:   Sun Dec 6 12:52:44 2020 +0100

    Check qual and compare for family tests
    
    Fixes #267. Hash table lookups assumed qual="any" compare="eq".
    Add a test too.

diff --git a/src/fccfg.c b/src/fccfg.c
index 7b857bf..00a94e5 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -1714,6 +1714,7 @@ FcConfigMatchValueList (FcPattern	*p,
     FcExpr	    *e = t->expr;
     FcValue	    value;
     FcValueList	    *v;
+    FcOp            op;
 
     while (e)
     {
@@ -1731,10 +1732,23 @@ FcConfigMatchValueList (FcPattern	*p,
 
         if (t->object == FC_FAMILY_OBJECT && table)
         {
-            if (!FamilyTableLookup (table, t->op, FcValueString (&value)))
+            op = FC_OP_GET_OP (t->op);
+            if (op == FcOpEqual || op == FcOpListing)
             {
+                if (!FamilyTableLookup (table, t->op, FcValueString (&value)))
+                {
                     ret = 0;
                     goto done;
+                }
+            }
+            if (op == FcOpNotEqual && t->qual == FcQualAll)
+            {
+                ret = 0;
+                if (!FamilyTableLookup (table, t->op, FcValueString (&value)))
+                {
+                    ret = values;
+                }
+                goto done;
             }
         }
 	for (v = values; v; v = FcValueListNext(v))
diff --git a/test/Makefile.am b/test/Makefile.am
index 1a9b293..30d8c2a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -167,6 +167,10 @@ check_PROGRAMS += test-issue180
 test_issue180_LDADD = $(top_builddir)/src/libfontconfig.la
 TESTS += test-issue180
 
+check_PROGRAMS += test-family-matching
+test_family_matching_LDADD = $(top_builddir)/src/libfontconfig.la
+TESTS += test-family-matching
+
 EXTRA_DIST=run-test.sh run-test-conf.sh $(LOG_COMPILER) $(TESTDATA) out.expected-long-family-names out.expected-no-long-family-names
 
 CLEANFILES =		\
diff --git a/test/meson.build b/test/meson.build
index 96b30a9..59de427 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -6,6 +6,7 @@ tests = [
   ['test-bz106618.c'],
   ['test-bz1744377.c'],
   ['test-issue180.c'],
+  ['test-family-matching.c'],
 ]
 
 if host_machine.system() != 'windows'
diff --git a/test/test-family-matching.c b/test/test-family-matching.c
new file mode 100644
index 0000000..9fab36c
--- /dev/null
+++ b/test/test-family-matching.c
@@ -0,0 +1,228 @@
+/*
+ * fontconfig/test/test-family-matching.c
+ *
+ * Copyright © 2020 Zoltan Vandrus
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The authors make no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fontconfig/fontconfig.h>
+
+#define FC_TEST_RESULT "testresult"
+
+typedef enum _TestMatchResult {
+    TestMatch,
+    TestNoMatch,
+    TestMatchError
+} TestMatchResult;
+
+typedef enum _TestResult {
+    TestPassed,
+    TestFailed,
+    TestError
+} TestResult;
+
+static TestMatchResult
+TestMatchPattern (const char *test, FcPattern *p)
+{
+    const FcChar8 *xml_pre = (const FcChar8 *) ""
+        "<fontconfig>\n"
+        "  <match>\n"
+        "";
+
+    const FcChar8 *xml_post = (const FcChar8 *) ""
+        "    <edit name=\""FC_TEST_RESULT"\">\n"
+        "      <bool>true</bool>\n"
+        "    </edit>\n"
+        "  </match>\n"
+        "</fontconfig>\n"
+        "";
+
+    FcChar8 *xml, *concat;
+    FcConfig *cfg;
+    FcResult result;
+    FcBool dummy;
+    TestResult ret = TestMatchError;
+
+    FcPattern *pat = FcPatternDuplicate (p);
+    if (!pat)
+    {
+        fprintf (stderr, "Unable to duplicate pattern.\n");
+        goto bail0;
+    }
+
+    concat = FcStrPlus (xml_pre, (const FcChar8 *) test);
+    if (!concat)
+    {
+        fprintf (stderr, "Concatenation failed.\n");
+        goto bail0;
+    }
+
+    xml = FcStrPlus (concat, xml_post);
+    FcStrFree (concat);
+    if (!xml)
+    {
+        fprintf (stderr, "Concatenation failed.\n");
+        goto bail0;
+    }
+
+    cfg = FcConfigCreate ();
+    if (!cfg)
+    {
+        fprintf (stderr, "Unable to create a new empty config.\n");
+        return TestMatchError;
+    }
+
+    if (!FcConfigParseAndLoadFromMemory (cfg, xml, FcTrue))
+    {
+        fprintf (stderr, "Unable to load a config from memory.\n");
+        goto bail1;
+    }
+
+    if (!FcConfigSubstitute (cfg, pat, FcMatchPattern))
+    {
+        fprintf (stderr, "Unable to substitute config.\n");
+        goto bail1;
+    }
+
+    result = FcPatternGetBool (pat, FC_TEST_RESULT, 0, &dummy);
+    switch (result) {
+    case FcResultMatch:
+        ret = TestMatch;
+        break;
+    case FcResultNoMatch:
+        ret = TestNoMatch;
+        break;
+    default:
+        fprintf (stderr, "Unable to check pattern.\n");
+        break;
+    }
+
+bail1:
+    FcConfigDestroy (cfg);
+bail0:
+    FcPatternDestroy (pat);
+    return ret;
+}
+
+static TestResult
+TestShouldMatchPattern(const char* test, FcPattern *pat, int negate)
+{
+    switch (TestMatchPattern (test, pat)) {
+    case TestMatch:
+        if (!negate) {
+            return TestPassed;
+        }
+        else
+        {
+            printf ("Following test unexpectedly matched:\n%s", test);
+            printf ("on\n");
+            FcPatternPrint (pat);
+            return TestFailed;
+        }
+        break;
+    case TestNoMatch:
+        if (!negate) {
+            printf ("Following test should have matched:\n%s", test);
+            printf ("on\n");
+            FcPatternPrint (pat);
+            return TestFailed;
+        }
+        else
+        {
+            return TestPassed;
+        }
+        break;
+    case TestMatchError:
+        return TestError;
+        break;
+    default:
+        fprintf (stderr, "This shouldn't have been reached.\n");
+        return TestError;
+    }
+}
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+static TestResult
+UpdateResult (TestResult* res, TestResult resNew)
+{
+    *res = MAX(*res, resNew);
+    return *res;
+}
+
+static TestResult
+TestFamily (void)
+{
+    const char *test;
+    TestResult res = TestPassed;
+
+    FcPattern *pat = FcPatternBuild (NULL,
+        FC_FAMILY, FcTypeString, "family1",
+        FC_FAMILY, FcTypeString, "family2",
+        FC_FAMILY, FcTypeString, "family3",
+        NULL);
+
+    if (!pat)
+    {
+        fprintf (stderr, "Unable to build pattern.\n");
+        return TestError;
+    }
+
+    #define SHOULD_MATCH(p,t) \
+        UpdateResult (&res, TestShouldMatchPattern (t, p, 0))
+    #define SHOULD_NOT_MATCH(p,t) \
+        UpdateResult (&res, TestShouldMatchPattern (t, p, 1))
+
+    test = "<test qual=\"all\" name=\"family\" compare=\"not_eq\">\n"
+           "    <string>foo</string>\n"
+           "</test>\n"
+           "";
+    SHOULD_MATCH(pat, test);
+
+    test = ""
+           "<test qual=\"all\" name=\"family\" compare=\"not_eq\">\n"
+           "    <string>family2</string>\n"
+           "</test>\n"
+           "";
+    SHOULD_NOT_MATCH(pat, test);
+
+    test = ""
+           "<test qual=\"any\" name=\"family\" compare=\"eq\">\n"
+           "    <string>family3</string>\n"
+           "</test>\n"
+           "";
+    SHOULD_MATCH(pat, test);
+
+    test = ""
+           "<test qual=\"any\" name=\"family\" compare=\"eq\">\n"
+           "    <string>foo</string>\n"
+           "</test>\n"
+           "";
+    SHOULD_NOT_MATCH(pat, test);
+
+    return res;
+}
+
+int
+main (void)
+{
+    return (TestFamily ());
+}


More information about the Fontconfig mailing list