Fix the behavior of intermixed tests end edits in match
authorAkira TAGOH <akira@tagoh.org>
Fri, 28 Jun 2013 06:54:38 +0000 (15:54 +0900)
committerAkira TAGOH <akira@tagoh.org>
Fri, 28 Jun 2013 06:54:38 +0000 (15:54 +0900)
to get the following recipe working:

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

as:

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

src/fccfg.c
src/fcint.h
src/fcxml.c

index 9c0be24..3cf31e8 100644 (file)
@@ -226,20 +226,25 @@ FcSubstDestroy (FcSubst *s)
 FcExpr *
 FcConfigAllocExpr (FcConfig *config)
 {
-  if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end)
-  {
-    FcExprPage *new_page;
+    FcExpr *e;
 
-    new_page = malloc (sizeof (FcExprPage));
-    if (!new_page)
-      return 0;
+    if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end)
+    {
+       FcExprPage *new_page;
 
-    new_page->next_page = config->expr_pool;
-    new_page->next = new_page->exprs;
-    config->expr_pool = new_page;
-  }
+       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;
+    }
+
+    e = config->expr_pool->next++;
+    FcRefInit (&e->ref, 1);
 
-  return config->expr_pool->next++;
+    return e;
 }
 
 FcConfig *
index 0137dee..92777ea 100644 (file)
@@ -240,6 +240,7 @@ typedef struct _FcExprName {
 
 typedef struct _FcExpr {
     FcOp   op;
+    FcRef  ref;
     union {
        int         ival;
        double      dval;
index 7e03230..4b8049f 100644 (file)
@@ -223,11 +223,24 @@ FcExprCreateOp (FcConfig *config, FcExpr *left, FcOp op, FcExpr *right)
     return e;
 }
 
+static FcExpr *
+FcExprReference (FcExpr *e)
+{
+    if (e)
+    {
+       FcRefInc (&e->ref);
+    }
+
+    return e;
+}
+
 static void
 FcExprDestroy (FcExpr *e)
 {
     if (!e)
        return;
+    if (FcRefDec (&e->ref) != 1)
+       return;
     switch (FC_OP_GET_OP (e->op)) {
     case FcOpInteger:
        break;
@@ -727,6 +740,21 @@ FcTestCreate (FcConfigParse *parse,
     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 *
 FcEditCreate (FcConfigParse    *parse,
              FcObject          object,
@@ -2401,7 +2429,7 @@ FcParseMatch (FcConfigParse *parse)
     FcVStack       *vstack;
     FcBool           tested = FcFalse;
     FcSubstStack    *sstack = NULL;
-    int              len, pos = 0;
+    int              len, pos = 0, i;
 
     kind_name = FcConfigGetAttribute (parse, "target");
     if (!kind_name)
@@ -2438,6 +2466,13 @@ FcParseMatch (FcConfigParse *parse)
            test = vstack->u.test;
            vstack->tag = FcVStackNone;
            tested = FcTrue;
+           for (i = 0; i < pos; i++)
+           {
+               FcTest *t = FcTestDuplicate(test);
+
+               t->next = sstack[i].test;
+               sstack[i].test = t;
+           }
            break;
        case FcVStackEdit:
            /* due to the reverse traversal, <edit> node appears faster than