aboutsummaryrefslogtreecommitdiff
path: root/fontconfig
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig')
-rw-r--r--fontconfig/configure.ac50
-rw-r--r--fontconfig/src/fccfg.c364
-rw-r--r--fontconfig/src/fcdbg.c39
-rw-r--r--fontconfig/src/fcint.h33
-rw-r--r--fontconfig/src/fcxml.c210
5 files changed, 360 insertions, 336 deletions
diff --git a/fontconfig/configure.ac b/fontconfig/configure.ac
index a2b1c72f4..aeb151331 100644
--- a/fontconfig/configure.ac
+++ b/fontconfig/configure.ac
@@ -161,35 +161,37 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([[
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_POSIX_FADVISE], [1], [Define to 1 if you have the 'posix_fadvise' function.])
],[AC_MSG_RESULT([no])])
-AC_MSG_CHECKING([for scandir])
-AC_LINK_IFELSE([AC_LANG_SOURCE([[
- #include <dirent.h>
- int comp(const struct dirent **, const struct dirent **);
- int comp(const struct dirent **a, const struct dirent **b) { return 0; }
- int main(void) {
- struct dirent **d;
- return scandir(".", &d, 0, &comp) >= 0;
- }
- ]])],[
- AC_MSG_RESULT([yes])
- AC_DEFINE([HAVE_SCANDIR], [1], [Define to 1 if you have the 'scandir' function.])
- ],[
- AC_LINK_IFELSE([AC_LANG_SOURCE([[
- #include <dirent.h>
- int comp(const void *, const void *);
- int comp(const void *a, const void *b) { return 0; }
- int main(void) {
- struct dirent **d;
- return scandir(".", &d, 0, &comp) >= 0;
- }
+if test "$os_win32" = "no"; then
+ AC_MSG_CHECKING([for scandir])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+ #include <dirent.h>
+ int comp(const struct dirent **, const struct dirent **);
+ int comp(const struct dirent **a, const struct dirent **b) { return 0; }
+ int main(void) {
+ struct dirent **d;
+ return scandir(".", &d, 0, &comp) >= 0;
+ }
]])],[
AC_MSG_RESULT([yes])
- AC_DEFINE([HAVE_SCANDIR_VOID_P], [1], [Define to 1 if you have the 'scandir' function with int (* compar)(const void *, const void *)])
+ AC_DEFINE([HAVE_SCANDIR], [1], [Define to 1 if you have the 'scandir' function.])
],[
- AC_MSG_ERROR([
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+ #include <dirent.h>
+ int comp(const void *, const void *);
+ int comp(const void *a, const void *b) { return 0; }
+ int main(void) {
+ struct dirent **d;
+ return scandir(".", &d, 0, &comp) >= 0;
+ }
+ ]])],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_SCANDIR_VOID_P], [1], [Define to 1 if you have the 'scandir' function with int (* compar)(const void *, const void *)])
+ ],[
+ AC_MSG_ERROR([
*** No scandir function available.])
+ ])
])
- ])
+fi
CFLAGS="$fc_saved_CFLAGS"
#
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index 9c0be24a3..7ea94b846 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -214,10 +214,8 @@ FcSubstDestroy (FcSubst *s)
while (s)
{
n = s->next;
- if (s->test)
- FcTestDestroy (s->test);
- if (s->edit)
- FcEditDestroy (s->edit);
+ if (s->rule)
+ FcRuleDestroy (s->rule);
free (s);
s = n;
}
@@ -226,20 +224,20 @@ FcSubstDestroy (FcSubst *s)
FcExpr *
FcConfigAllocExpr (FcConfig *config)
{
- if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end)
- {
- FcExprPage *new_page;
+ if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end)
+ {
+ FcExprPage *new_page;
- new_page = malloc (sizeof (FcExprPage));
- if (!new_page)
- return 0;
+ new_page = malloc (sizeof (FcExprPage));
+ if (!new_page)
+ return 0;
- new_page->next_page = config->expr_pool;
- new_page->next = new_page->exprs;
- config->expr_pool = new_page;
- }
+ new_page->next_page = config->expr_pool;
+ new_page->next = new_page->exprs;
+ config->expr_pool = new_page;
+ }
- return config->expr_pool->next++;
+ return config->expr_pool->next++;
}
FcConfig *
@@ -644,15 +642,13 @@ FcConfigSetRescanInverval (FcConfig *config, int rescanInterval)
return FcConfigSetRescanInterval (config, rescanInterval);
}
-
FcBool
-FcConfigAddEdit (FcConfig *config,
- FcTest *test,
- FcEdit *edit,
+FcConfigAddRule (FcConfig *config,
+ FcRule *rule,
FcMatchKind kind)
{
FcSubst *subst, **prev;
- FcTest *t;
+ FcRule *r;
int num;
switch (kind) {
@@ -673,15 +669,18 @@ FcConfigAddEdit (FcConfig *config,
return FcFalse;
for (; *prev; prev = &(*prev)->next);
*prev = subst;
- subst->next = 0;
- subst->test = test;
- subst->edit = edit;
+ subst->next = NULL;
+ subst->rule = rule;
num = 0;
- for (t = test; t; t = t->next)
+ for (r = rule; r; r = r->next)
{
- if (t->kind == FcMatchDefault)
- t->kind = kind;
- num++;
+ if (r->type == FcRuleTest)
+ {
+ if (r->u.test &&
+ r->u.test->kind == FcMatchDefault)
+ r->u.test->kind = kind;
+ num++;
+ }
}
if (config->maxObjects < num)
config->maxObjects = num;
@@ -1486,13 +1485,12 @@ FcConfigSubstituteWithPat (FcConfig *config,
{
FcValue v;
FcSubst *s;
- FcSubState *st;
- int i;
- FcTest *t;
- FcEdit *e;
- FcValueList *l;
+ FcRule *r;
+ FcValueList *l, *value = NULL;
FcPattern *m;
FcStrSet *strs;
+ FcPatternElt *elt = NULL;
+ FcObject object = FC_INVALID_OBJECT;
if (!config)
{
@@ -1537,10 +1535,6 @@ FcConfigSubstituteWithPat (FcConfig *config,
return FcFalse;
}
- st = (FcSubState *) malloc (config->maxObjects * sizeof (FcSubState));
- if (!st && config->maxObjects)
- return FcFalse;
-
if (FcDebug () & FC_DBG_EDIT)
{
printf ("FcConfigSubstitute ");
@@ -1548,194 +1542,174 @@ FcConfigSubstituteWithPat (FcConfig *config,
}
for (; s; s = s->next)
{
- /*
- * Check the tests to see if
- * they all match the pattern
- */
- for (t = s->test, i = 0; t; t = t->next, i++)
+ r = s->rule;
+ for (; r; r = r->next)
{
- if (FcDebug () & FC_DBG_EDIT)
- {
- printf ("FcConfigSubstitute test ");
- FcTestPrint (t);
- }
- st[i].elt = 0;
- if (kind == FcMatchFont && t->kind == FcMatchPattern)
- m = p_pat;
- else
- m = p;
- if (m)
- st[i].elt = FcPatternObjectFindElt (m, t->object);
- else
- st[i].elt = 0;
- /*
- * If there's no such field in the font,
- * then FcQualAll matches while FcQualAny does not
- */
- if (!st[i].elt)
- {
- if (t->qual == FcQualAll)
+ switch (r->type) {
+ case FcRuleUnknown:
+ /* shouldn't be reached */
+ break;
+ case FcRuleTest:
+ /*
+ * Check the tests to see if
+ * they all match the pattern
+ */
+ if (FcDebug () & FC_DBG_EDIT)
{
- st[i].value = 0;
- continue;
+ printf ("FcConfigSubstitute test ");
+ FcTestPrint (r->u.test);
}
+ if (kind == FcMatchFont && r->u.test->kind == FcMatchPattern)
+ m = p_pat;
else
- break;
- }
- /*
- * Check to see if there is a match, mark the location
- * to apply match-relative edits
- */
- st[i].value = FcConfigMatchValueList (m, p_pat, kind, t, st[i].elt->values);
- if (!st[i].value)
- break;
- if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
- break;
- if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values)
- break;
- }
- if (t)
- {
- if (FcDebug () & FC_DBG_EDIT)
- printf ("No match\n");
- continue;
- }
- if (FcDebug () & FC_DBG_EDIT)
- {
- printf ("Substitute ");
- FcSubstPrint (s);
- }
- for (e = s->edit; e; e = e->next)
- {
- /*
- * Evaluate the list of expressions
- */
- l = FcConfigValues (p, p_pat,kind, e->expr, e->binding);
- /*
- * Locate any test associated with this field, skipping
- * tests associated with the pattern when substituting in
- * the font
- */
- for (t = s->test, i = 0; t; t = t->next, i++)
- {
- if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
- t->object == e->object)
+ m = p;
+ if (m)
+ elt = FcPatternObjectFindElt (m, r->u.test->object);
+ else
+ elt = NULL;
+ /*
+ * If there's no such field in the font,
+ * then FcQualAll matches while FcQualAny does not
+ */
+ if (!elt)
{
- /*
- * KLUDGE - the pattern may have been reallocated or
- * things may have been inserted or deleted above
- * this element by other edits. Go back and find
- * the element again
- */
- if (e != s->edit && st[i].elt)
- st[i].elt = FcPatternObjectFindElt (p, t->object);
- if (!st[i].elt)
- t = 0;
- break;
+ if (r->u.test->qual == FcQualAll)
+ {
+ value = NULL;
+ continue;
+ }
+ else
+ {
+ if (FcDebug () & FC_DBG_EDIT)
+ printf ("No match\n");
+ goto bail;
+ }
}
- }
- switch (FC_OP_GET_OP (e->op)) {
- case FcOpAssign:
/*
- * If there was a test, then replace the matched
- * value with the new list of values
+ * Check to see if there is a match, mark the location
+ * to apply match-relative edits
*/
- if (t)
+ value = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt->values);
+ if (!value ||
+ (r->u.test->qual == FcQualFirst && value != elt->values) ||
+ (r->u.test->qual == FcQualNotFirst && value == elt->values))
{
- FcValueList *thisValue = st[i].value;
- FcValueList *nextValue = thisValue;
-
+ if (FcDebug () & FC_DBG_EDIT)
+ printf ("No match\n");
+ goto bail;
+ }
+ object = r->u.test->object;
+ break;
+ case FcRuleEdit:
+ if (FcDebug () & FC_DBG_EDIT)
+ {
+ printf ("Substitute ");
+ FcEditPrint (r->u.edit);
+ printf ("\n\n");
+ }
+ /*
+ * Evaluate the list of expressions
+ */
+ l = FcConfigValues (p, p_pat,kind, r->u.edit->expr, r->u.edit->binding);
+ /*
+ * Locate any test associated with this field, skipping
+ * tests associated with the pattern when substituting in
+ * the font
+ */
+ if (object != r->u.edit->object)
+ value = NULL;
+
+ switch (FC_OP_GET_OP (r->u.edit->op)) {
+ case FcOpAssign:
/*
- * Append the new list of values after the current value
+ * If there was a test, then replace the matched
+ * value with the new list of values
*/
- FcConfigAdd (&st[i].elt->values, thisValue, FcTrue, l, e->object);
+ if (value)
+ {
+ FcValueList *thisValue = value;
+ FcValueList *nextValue = thisValue;
+
+ /*
+ * Append the new list of values after the current value
+ */
+ FcConfigAdd (&elt->values, thisValue, FcTrue, l, r->u.edit->object);
+ /*
+ * Delete the marked value
+ */
+ if (thisValue)
+ FcConfigDel (&elt->values, thisValue);
+ /*
+ * Adjust a pointer into the value list to ensure
+ * future edits occur at the same place
+ */
+ value = nextValue;
+ break;
+ }
+ /* fall through ... */
+ case FcOpAssignReplace:
/*
- * Delete the marked value
+ * Delete all of the values and insert
+ * the new set
*/
- if (thisValue)
- FcConfigDel (&st[i].elt->values, thisValue);
+ FcConfigPatternDel (p, r->u.edit->object);
+ FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
/*
- * Adjust any pointers into the value list to ensure
- * future edits occur at the same place
+ * Adjust a pointer into the value list as they no
+ * longer point to anything valid
*/
- for (t = s->test, i = 0; t; t = t->next, i++)
+ value = NULL;
+ break;
+ case FcOpPrepend:
+ if (value)
{
- if (st[i].value == thisValue)
- st[i].value = nextValue;
+ FcConfigAdd (&elt->values, value, FcFalse, l, r->u.edit->object);
+ break;
}
+ /* fall through ... */
+ case FcOpPrependFirst:
+ FcConfigPatternAdd (p, r->u.edit->object, l, FcFalse);
break;
- }
- /* fall through ... */
- case FcOpAssignReplace:
- /*
- * Delete all of the values and insert
- * the new set
- */
- FcConfigPatternDel (p, e->object);
- FcConfigPatternAdd (p, e->object, l, FcTrue);
- /*
- * Adjust any pointers into the value list as they no
- * longer point to anything valid
- */
- if (t)
- {
- FcPatternElt *thisElt = st[i].elt;
- for (t = s->test, i = 0; t; t = t->next, i++)
+ case FcOpAppend:
+ if (value)
{
- if (st[i].elt == thisElt)
- st[i].value = 0;
+ FcConfigAdd (&elt->values, value, FcTrue, l, r->u.edit->object);
+ break;
}
- }
- break;
- case FcOpPrepend:
- if (t)
- {
- FcConfigAdd (&st[i].elt->values, st[i].value, FcFalse, l, e->object);
+ /* fall through ... */
+ case FcOpAppendLast:
+ FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
break;
- }
- /* fall through ... */
- case FcOpPrependFirst:
- FcConfigPatternAdd (p, e->object, l, FcFalse);
- break;
- case FcOpAppend:
- if (t)
- {
- FcConfigAdd (&st[i].elt->values, st[i].value, FcTrue, l, e->object);
+ case FcOpDelete:
+ if (value)
+ {
+ FcConfigDel (&elt->values, value);
+ break;
+ }
+ /* fall through ... */
+ case FcOpDeleteAll:
+ FcConfigPatternDel (p, r->u.edit->object);
+ break;
+ default:
+ FcValueListDestroy (l);
break;
}
- /* fall through ... */
- case FcOpAppendLast:
- FcConfigPatternAdd (p, e->object, l, FcTrue);
- break;
- case FcOpDelete:
- if (t)
+ /*
+ * Now go through the pattern and eliminate
+ * any properties without data
+ */
+ FcConfigPatternCanon (p, r->u.edit->object);
+
+ if (FcDebug () & FC_DBG_EDIT)
{
- FcConfigDel (&st[i].elt->values, st[i].value);
- break;
+ printf ("FcConfigSubstitute edit");
+ FcPatternPrint (p);
}
- /* fall through ... */
- case FcOpDeleteAll:
- FcConfigPatternDel (p, e->object);
- break;
- default:
- FcValueListDestroy (l);
break;
}
}
- /*
- * Now go through the pattern and eliminate
- * any properties without data
- */
- for (e = s->edit; e; e = e->next)
- FcConfigPatternCanon (p, e->object);
-
- if (FcDebug () & FC_DBG_EDIT)
- {
- printf ("FcConfigSubstitute edit");
- FcPatternPrint (p);
- }
+ bail:;
}
- free (st);
if (FcDebug () & FC_DBG_EDIT)
{
printf ("FcConfigSubstitute done");
diff --git a/fontconfig/src/fcdbg.c b/fontconfig/src/fcdbg.c
index ce642140c..d74bc2769 100644
--- a/fontconfig/src/fcdbg.c
+++ b/fontconfig/src/fcdbg.c
@@ -427,21 +427,38 @@ FcEditPrint (const FcEdit *edit)
void
FcSubstPrint (const FcSubst *subst)
{
- FcEdit *e;
- FcTest *t;
+ FcRule *r;
+ FcRuleType last_type = FcRuleUnknown;
printf ("match\n");
- for (t = subst->test; t; t = t->next)
- {
- printf ("\t");
- FcTestPrint (t);
- }
- printf ("edit\n");
- for (e = subst->edit; e; e = e->next)
+ for (r = subst->rule; r; r = r->next)
{
+ if (last_type != r->type)
+ {
+ switch (r->type) {
+ case FcRuleTest:
+ printf ("[test]\n");
+ break;
+ case FcRuleEdit:
+ printf ("[edit]\n");
+ break;
+ default:
+ break;
+ }
+ last_type = r->type;
+ }
printf ("\t");
- FcEditPrint (e);
- printf (";\n");
+ switch (r->type) {
+ case FcRuleTest:
+ FcTestPrint (r->u.test);
+ break;
+ case FcRuleEdit:
+ FcEditPrint (r->u.edit);
+ printf (";\n");
+ break;
+ default:
+ break;
+ }
}
printf ("\n");
}
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index 0137deeb4..fe523fb7c 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -37,6 +37,7 @@
#include <ctype.h>
#include <assert.h>
#include <errno.h>
+#include <limits.h>
#include <unistd.h>
#include <stddef.h>
#include <sys/types.h>
@@ -85,7 +86,7 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA;
#define FC_DBG_CONFIG 1024
#define FC_DBG_LANGSET 2048
-#define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
+#define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] FC_UNUSED
#define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond))
#define FC_ASSERT_STATIC(_cond) _FC_ASSERT_STATIC0 (__LINE__, (_cond))
@@ -109,7 +110,7 @@ FC_ASSERT_STATIC (sizeof (FcRef) == sizeof (int));
typedef enum _FcValueBinding {
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame,
/* to make sure sizeof (FcValueBinding) == 4 even with -fshort-enums */
- FcValueBindingEnd = 0xffffffff
+ FcValueBindingEnd = INT_MAX
} FcValueBinding;
#define FcStrdup(s) ((FcChar8 *) strdup ((const char *) (s)))
@@ -273,7 +274,6 @@ typedef enum _FcQual {
#define FcMatchDefault ((FcMatchKind) -1)
typedef struct _FcTest {
- struct _FcTest *next;
FcMatchKind kind;
FcQual qual;
FcObject object;
@@ -282,17 +282,28 @@ typedef struct _FcTest {
} FcTest;
typedef struct _FcEdit {
- struct _FcEdit *next;
FcObject object;
FcOp op;
FcExpr *expr;
FcValueBinding binding;
} FcEdit;
+typedef enum _FcRuleType {
+ FcRuleUnknown, FcRuleTest, FcRuleEdit
+} FcRuleType;
+
+typedef struct _FcRule {
+ struct _FcRule *next;
+ FcRuleType type;
+ union {
+ FcTest *test;
+ FcEdit *edit;
+ } u;
+} FcRule;
+
typedef struct _FcSubst {
struct _FcSubst *next;
- FcTest *test;
- FcEdit *edit;
+ FcRule *rule;
} FcSubst;
typedef struct _FcCharLeaf {
@@ -612,10 +623,9 @@ FcPrivate FcBool
FcConfigAddBlank (FcConfig *config,
FcChar32 blank);
-FcPrivate FcBool
-FcConfigAddEdit (FcConfig *config,
- FcTest *test,
- FcEdit *edit,
+FcBool
+FcConfigAddRule (FcConfig *config,
+ FcRule *rule,
FcMatchKind kind);
FcPrivate void
@@ -842,6 +852,9 @@ FcTestDestroy (FcTest *test);
FcPrivate void
FcEditDestroy (FcEdit *e);
+void
+FcRuleDestroy (FcRule *rule);
+
/* fclang.c */
FcPrivate FcLangSet *
FcFreeTypeLangSet (const FcCharSet *charset,
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index 7e0323064..61dc6300b 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -62,12 +62,28 @@ FcExprDestroy (FcExpr *e);
void
FcTestDestroy (FcTest *test)
{
- if (test->next)
- FcTestDestroy (test->next);
FcExprDestroy (test->expr);
free (test);
}
+void
+FcRuleDestroy (FcRule *rule)
+{
+ if (rule->next)
+ FcRuleDestroy (rule->next);
+ switch (rule->type) {
+ case FcRuleTest:
+ FcTestDestroy (rule->u.test);
+ break;
+ case FcRuleEdit:
+ FcEditDestroy (rule->u.edit);
+ break;
+ default:
+ break;
+ }
+ free (rule);
+}
+
static FcExpr *
FcExprCreateInteger (FcConfig *config, int i)
{
@@ -300,8 +316,6 @@ FcExprDestroy (FcExpr *e)
void
FcEditDestroy (FcEdit *e)
{
- if (e->next)
- FcEditDestroy (e->next);
if (e->expr)
FcExprDestroy (e->expr);
free (e);
@@ -714,7 +728,6 @@ FcTestCreate (FcConfigParse *parse,
{
const FcObjectType *o;
- test->next = 0;
test->kind = kind;
test->qual = qual;
test->object = FcObjectFromName ((const char *) field);
@@ -740,7 +753,6 @@ FcEditCreate (FcConfigParse *parse,
{
const FcObjectType *o;
- e->next = 0;
e->object = object;
e->op = op;
e->expr = expr;
@@ -752,6 +764,34 @@ FcEditCreate (FcConfigParse *parse,
return e;
}
+static FcRule *
+FcRuleCreate (FcRuleType type,
+ void *p)
+{
+ FcRule *r = (FcRule *) malloc (sizeof (FcRule));
+
+ if (!r)
+ return NULL;
+
+ r->next = NULL;
+ r->type = type;
+ switch (type)
+ {
+ case FcRuleTest:
+ r->u.test = (FcTest *) p;
+ break;
+ case FcRuleEdit:
+ r->u.edit = (FcEdit *) p;
+ break;
+ default:
+ free (r);
+ r = NULL;
+ break;
+ }
+
+ return r;
+}
+
static FcVStack *
FcVStackCreateAndPush (FcConfigParse *parse)
{
@@ -1657,9 +1697,9 @@ static void
FcParseAlias (FcConfigParse *parse)
{
FcExpr *family = 0, *accept = 0, *prefer = 0, *def = 0, *new = 0;
- FcEdit *edit = 0, *next;
+ FcEdit *edit = 0;
FcVStack *vstack;
- FcTest *test = NULL;
+ FcRule *rule = NULL, *r;
FcValueBinding binding;
if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding))
@@ -1704,8 +1744,14 @@ FcParseAlias (FcConfigParse *parse)
vstack->tag = FcVStackNone;
break;
case FcVStackTest:
- vstack->u.test->next = test;
- test = vstack->u.test;
+ if (rule)
+ {
+ r = FcRuleCreate (FcRuleTest, vstack->u.test);
+ r->next = rule;
+ rule = r;
+ }
+ else
+ rule = FcRuleCreate (FcRuleTest, vstack->u.test);
vstack->tag = FcVStackNone;
break;
default:
@@ -1723,8 +1769,35 @@ FcParseAlias (FcConfigParse *parse)
FcExprDestroy (accept);
if (def)
FcExprDestroy (def);
+ if (rule)
+ FcRuleDestroy (rule);
return;
}
+ if (!prefer &&
+ !accept &&
+ !def)
+ {
+ FcExprDestroy (family);
+ return;
+ }
+ else
+ {
+ FcTest *t = FcTestCreate (parse, FcMatchPattern,
+ FcQualAny,
+ (FcChar8 *) FC_FAMILY,
+ FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks),
+ family);
+ if (rule)
+ {
+ for (r = rule; r->next; r = r->next);
+ r->next = FcRuleCreate (FcRuleTest, t);
+ r = r->next;
+ }
+ else
+ {
+ r = rule = FcRuleCreate (FcRuleTest, t);
+ }
+ }
if (prefer)
{
edit = FcEditCreate (parse,
@@ -1732,60 +1805,46 @@ FcParseAlias (FcConfigParse *parse)
FcOpPrepend,
prefer,
binding);
- if (edit)
- edit->next = 0;
- else
+ if (!edit)
FcExprDestroy (prefer);
+ else
+ {
+ r->next = FcRuleCreate (FcRuleEdit, edit);
+ r = r->next;
+ }
}
if (accept)
{
- next = edit;
edit = FcEditCreate (parse,
FC_FAMILY_OBJECT,
FcOpAppend,
accept,
binding);
- if (edit)
- edit->next = next;
- else
+ if (!edit)
FcExprDestroy (accept);
+ else
+ {
+ r->next = FcRuleCreate (FcRuleEdit, edit);
+ r = r->next;
+ }
}
if (def)
{
- next = edit;
edit = FcEditCreate (parse,
FC_FAMILY_OBJECT,
FcOpAppendLast,
def,
binding);
- if (edit)
- edit->next = next;
- else
+ if (!edit)
FcExprDestroy (def);
- }
- if (edit)
- {
- FcTest *t = FcTestCreate (parse, FcMatchPattern,
- FcQualAny,
- (FcChar8 *) FC_FAMILY,
- FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks),
- family);
- if (test)
+ else
{
- FcTest *p = test;
-
- while (p->next)
- p = p->next;
- p->next = t;
+ r->next = FcRuleCreate (FcRuleEdit, edit);
+ r = r->next;
}
- else
- test = t;
- if (test)
- if (!FcConfigAddEdit (parse->config, test, edit, FcMatchPattern))
- FcTestDestroy (test);
}
- else
- FcExprDestroy (family);
+ if (!FcConfigAddRule (parse->config, rule, FcMatchPattern))
+ FcRuleDestroy (rule);
}
static FcExpr *
@@ -2386,22 +2445,14 @@ FcParseEdit (FcConfigParse *parse)
FcEditDestroy (edit);
}
-typedef struct FcSubstStack {
- FcTest *test;
- FcEdit *edit;
-} FcSubstStack;
-
static void
FcParseMatch (FcConfigParse *parse)
{
const FcChar8 *kind_name;
FcMatchKind kind;
- FcTest *test = 0;
FcEdit *edit = 0;
FcVStack *vstack;
- FcBool tested = FcFalse;
- FcSubstStack *sstack = NULL;
- int len, pos = 0;
+ FcRule *rule = NULL, *r;
kind_name = FcConfigGetAttribute (parse, "target");
if (!kind_name)
@@ -2420,48 +2471,29 @@ FcParseMatch (FcConfigParse *parse)
return;
}
}
- len = FcVStackElements(parse);
- if (len > 0)
- {
- sstack = malloc (sizeof (FcSubstStack) * (len + 1));
- if (!sstack)
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- return;
- }
- }
while ((vstack = FcVStackPeek (parse)))
{
switch ((int) vstack->tag) {
case FcVStackTest:
- vstack->u.test->next = test;
- test = vstack->u.test;
+ r = FcRuleCreate (FcRuleTest, vstack->u.test);
+ if (rule)
+ r->next = rule;
+ rule = r;
vstack->tag = FcVStackNone;
- tested = FcTrue;
break;
case FcVStackEdit:
- /* due to the reverse traversal, <edit> node appears faster than
- * <test> node if any. so we have to deal with it here rather than
- * the above in FcVStackTest, and put recipes in reverse order.
- */
- if (tested)
- {
- sstack[pos].test = test;
- sstack[pos].edit = edit;
- pos++;
- test = NULL;
- edit = NULL;
- tested = FcFalse;
- }
- vstack->u.edit->next = edit;
- edit = vstack->u.edit;
- vstack->tag = FcVStackNone;
- if (kind == FcMatchScan && edit->object > FC_MAX_BASE_OBJECT)
+ if (kind == FcMatchScan && vstack->u.edit->object > FC_MAX_BASE_OBJECT)
{
FcConfigMessage (parse, FcSevereError,
"<match target=\"scan\"> cannot edit user-defined object \"%s\"",
FcObjectName(edit->object));
+ break;
}
+ r = FcRuleCreate (FcRuleEdit, vstack->u.edit);
+ if (rule)
+ r->next = rule;
+ rule = r;
+ vstack->tag = FcVStackNone;
break;
default:
FcConfigMessage (parse, FcSevereWarning, "invalid match element");
@@ -2469,22 +2501,8 @@ FcParseMatch (FcConfigParse *parse)
}
FcVStackPopAndDestroy (parse);
}
- if (!FcConfigAddEdit (parse->config, test, edit, kind))
+ if (!FcConfigAddRule (parse->config, rule, kind))
FcConfigMessage (parse, FcSevereError, "out of memory");
- if (sstack)
- {
- int i;
-
- for (i = 0; i < pos; i++)
- {
- if (!FcConfigAddEdit (parse->config, sstack[pos - i - 1].test, sstack[pos - i - 1].edit, kind))
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- return;
- }
- }
- free (sstack);
- }
}
static void