Bug 59385 - Do the right thing for intermixed edit and test elements
This changes allows to have multiple mathcing rules in one <match> block in the same order. After this changes, the following thing will works as two matching rules: <match> <!-- rule 1 --> <test name="family" compare="eq"> <string>foo</string> </test> <edit name="foo" mode="append"> <string>foo</string> </edit> <!-- rule 2 --> <test name="foo" compare="eq"> <string>foo</string> </test> <edit name="foo" mode="append"> <string>bar</string> </edit> </match>
This commit is contained in:
parent
fb3b410998
commit
d26fb23c41
|
@ -140,7 +140,7 @@
|
|||
if 'target' is 'font', execute the match on the result of a font
|
||||
selection.
|
||||
-->
|
||||
<!ELEMENT match (test*, edit*)>
|
||||
<!ELEMENT match (test*, edit*)+>
|
||||
<!ATTLIST match
|
||||
target (pattern|font|scan) "pattern">
|
||||
|
||||
|
|
46
src/fcxml.c
46
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, <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;
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue