From d26fb23c41abd87422778bb38eea39f25ba3dc4a Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Fri, 25 Jan 2013 20:01:24 +0900 Subject: [PATCH] Bug 59385 - Do the right thing for intermixed edit and test elements This changes allows to have multiple mathcing rules in one block in the same order. After this changes, the following thing will works as two matching rules: foo foo foo bar --- fonts.dtd | 2 +- src/fcxml.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/fonts.dtd b/fonts.dtd index def8c21..664467d 100644 --- a/fonts.dtd +++ b/fonts.dtd @@ -140,7 +140,7 @@ if 'target' is 'font', execute the match on the result of a font selection. --> - + diff --git a/src/fcxml.c b/src/fcxml.c index 2a0d088..5981ea9 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -2375,6 +2375,11 @@ FcParseEdit (FcConfigParse *parse) FcEditDestroy (edit); } +typedef struct FcSubstStack { + FcTest *test; + FcEdit *edit; +} FcSubstStack; + static void FcParseMatch (FcConfigParse *parse) { @@ -2383,6 +2388,9 @@ FcParseMatch (FcConfigParse *parse) FcTest *test = 0; FcEdit *edit = 0; FcVStack *vstack; + FcBool tested = FcFalse; + FcSubstStack *sstack = NULL; + int len, pos = 0; kind_name = FcConfigGetAttribute (parse, "target"); if (!kind_name) @@ -2401,6 +2409,16 @@ 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) { @@ -2408,8 +2426,22 @@ FcParseMatch (FcConfigParse *parse) vstack->u.test->next = test; test = vstack->u.test; vstack->tag = FcVStackNone; + tested = FcTrue; break; case FcVStackEdit: + /* due to the reverse traversal, node appears faster than + * 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; @@ -2428,6 +2460,20 @@ FcParseMatch (FcConfigParse *parse) } if (!FcConfigAddEdit (parse->config, test, edit, 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