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
|
if 'target' is 'font', execute the match on the result of a font
|
||||||
selection.
|
selection.
|
||||||
-->
|
-->
|
||||||
<!ELEMENT match (test*, edit*)>
|
<!ELEMENT match (test*, edit*)+>
|
||||||
<!ATTLIST match
|
<!ATTLIST match
|
||||||
target (pattern|font|scan) "pattern">
|
target (pattern|font|scan) "pattern">
|
||||||
|
|
||||||
|
|
46
src/fcxml.c
46
src/fcxml.c
|
@ -2375,6 +2375,11 @@ FcParseEdit (FcConfigParse *parse)
|
||||||
FcEditDestroy (edit);
|
FcEditDestroy (edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct FcSubstStack {
|
||||||
|
FcTest *test;
|
||||||
|
FcEdit *edit;
|
||||||
|
} FcSubstStack;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FcParseMatch (FcConfigParse *parse)
|
FcParseMatch (FcConfigParse *parse)
|
||||||
{
|
{
|
||||||
|
@ -2383,6 +2388,9 @@ FcParseMatch (FcConfigParse *parse)
|
||||||
FcTest *test = 0;
|
FcTest *test = 0;
|
||||||
FcEdit *edit = 0;
|
FcEdit *edit = 0;
|
||||||
FcVStack *vstack;
|
FcVStack *vstack;
|
||||||
|
FcBool tested = FcFalse;
|
||||||
|
FcSubstStack *sstack = NULL;
|
||||||
|
int len, pos = 0;
|
||||||
|
|
||||||
kind_name = FcConfigGetAttribute (parse, "target");
|
kind_name = FcConfigGetAttribute (parse, "target");
|
||||||
if (!kind_name)
|
if (!kind_name)
|
||||||
|
@ -2401,6 +2409,16 @@ FcParseMatch (FcConfigParse *parse)
|
||||||
return;
|
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)))
|
while ((vstack = FcVStackPeek (parse)))
|
||||||
{
|
{
|
||||||
switch ((int) vstack->tag) {
|
switch ((int) vstack->tag) {
|
||||||
|
@ -2408,8 +2426,22 @@ FcParseMatch (FcConfigParse *parse)
|
||||||
vstack->u.test->next = test;
|
vstack->u.test->next = test;
|
||||||
test = vstack->u.test;
|
test = vstack->u.test;
|
||||||
vstack->tag = FcVStackNone;
|
vstack->tag = FcVStackNone;
|
||||||
|
tested = FcTrue;
|
||||||
break;
|
break;
|
||||||
case FcVStackEdit:
|
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;
|
vstack->u.edit->next = edit;
|
||||||
edit = vstack->u.edit;
|
edit = vstack->u.edit;
|
||||||
vstack->tag = FcVStackNone;
|
vstack->tag = FcVStackNone;
|
||||||
|
@ -2428,6 +2460,20 @@ FcParseMatch (FcConfigParse *parse)
|
||||||
}
|
}
|
||||||
if (!FcConfigAddEdit (parse->config, test, edit, kind))
|
if (!FcConfigAddEdit (parse->config, test, edit, kind))
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
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
|
static void
|
||||||
|
|
Loading…
Reference in New Issue