diff options
Diffstat (limited to 'fontconfig')
-rw-r--r-- | fontconfig/configure.ac | 50 | ||||
-rw-r--r-- | fontconfig/src/fccfg.c | 364 | ||||
-rw-r--r-- | fontconfig/src/fcdbg.c | 39 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 33 | ||||
-rw-r--r-- | fontconfig/src/fcxml.c | 210 |
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 |