Fix the behavior of intermixed tests end edits in match

to get the following recipe working:

<match>
  <test1 .../>
  <edit1 .../>
  <test2 .../>
  <edit2 .../>
</match>

as:

<match>
  <test1 .../>
  </edit1 .../>
</match>
<match>
  <test1 .../>
  <test2 .../>
  <edit2 .../>
</match>
This commit is contained in:
Akira TAGOH 2013-06-28 15:54:38 +09:00
parent 197d06c49b
commit 0907589a79
3 changed files with 53 additions and 12 deletions

View File

@ -226,6 +226,8 @@ FcSubstDestroy (FcSubst *s)
FcExpr * FcExpr *
FcConfigAllocExpr (FcConfig *config) FcConfigAllocExpr (FcConfig *config)
{ {
FcExpr *e;
if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end) if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end)
{ {
FcExprPage *new_page; FcExprPage *new_page;
@ -239,7 +241,10 @@ FcConfigAllocExpr (FcConfig *config)
config->expr_pool = new_page; config->expr_pool = new_page;
} }
return config->expr_pool->next++; e = config->expr_pool->next++;
FcRefInit (&e->ref, 1);
return e;
} }
FcConfig * FcConfig *

View File

@ -240,6 +240,7 @@ typedef struct _FcExprName {
typedef struct _FcExpr { typedef struct _FcExpr {
FcOp op; FcOp op;
FcRef ref;
union { union {
int ival; int ival;
double dval; double dval;

View File

@ -223,11 +223,24 @@ FcExprCreateOp (FcConfig *config, FcExpr *left, FcOp op, FcExpr *right)
return e; return e;
} }
static FcExpr *
FcExprReference (FcExpr *e)
{
if (e)
{
FcRefInc (&e->ref);
}
return e;
}
static void static void
FcExprDestroy (FcExpr *e) FcExprDestroy (FcExpr *e)
{ {
if (!e) if (!e)
return; return;
if (FcRefDec (&e->ref) != 1)
return;
switch (FC_OP_GET_OP (e->op)) { switch (FC_OP_GET_OP (e->op)) {
case FcOpInteger: case FcOpInteger:
break; break;
@ -727,6 +740,21 @@ FcTestCreate (FcConfigParse *parse,
return test; return test;
} }
static FcTest *
FcTestDuplicate (FcTest *test)
{
FcTest *retval = (FcTest *) malloc (sizeof (FcTest));
if (retval)
{
memcpy (retval, test, sizeof (FcTest));
retval->next = NULL;
retval->expr = FcExprReference (test->expr);
}
return retval;
}
static FcEdit * static FcEdit *
FcEditCreate (FcConfigParse *parse, FcEditCreate (FcConfigParse *parse,
FcObject object, FcObject object,
@ -2401,7 +2429,7 @@ FcParseMatch (FcConfigParse *parse)
FcVStack *vstack; FcVStack *vstack;
FcBool tested = FcFalse; FcBool tested = FcFalse;
FcSubstStack *sstack = NULL; FcSubstStack *sstack = NULL;
int len, pos = 0; int len, pos = 0, i;
kind_name = FcConfigGetAttribute (parse, "target"); kind_name = FcConfigGetAttribute (parse, "target");
if (!kind_name) if (!kind_name)
@ -2438,6 +2466,13 @@ FcParseMatch (FcConfigParse *parse)
test = vstack->u.test; test = vstack->u.test;
vstack->tag = FcVStackNone; vstack->tag = FcVStackNone;
tested = FcTrue; tested = FcTrue;
for (i = 0; i < pos; i++)
{
FcTest *t = FcTestDuplicate(test);
t->next = sstack[i].test;
sstack[i].test = t;
}
break; break;
case FcVStackEdit: case FcVStackEdit:
/* due to the reverse traversal, <edit> node appears faster than /* due to the reverse traversal, <edit> node appears faster than