aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src/fcxml.c
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src/fcxml.c')
-rw-r--r--fontconfig/src/fcxml.c210
1 files changed, 114 insertions, 96 deletions
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index 7e0323064..61dc6300b 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -62,12 +62,28 @@ FcExprDestroy (FcExpr *e);
void
FcTestDestroy (FcTest *test)
{
- if (test->next)
- FcTestDestroy (test->next);
FcExprDestroy (test->expr);
free (test);
}
+void
+FcRuleDestroy (FcRule *rule)
+{
+ if (rule->next)
+ FcRuleDestroy (rule->next);
+ switch (rule->type) {
+ case FcRuleTest:
+ FcTestDestroy (rule->u.test);
+ break;
+ case FcRuleEdit:
+ FcEditDestroy (rule->u.edit);
+ break;
+ default:
+ break;
+ }
+ free (rule);
+}
+
static FcExpr *
FcExprCreateInteger (FcConfig *config, int i)
{
@@ -300,8 +316,6 @@ FcExprDestroy (FcExpr *e)
void
FcEditDestroy (FcEdit *e)
{
- if (e->next)
- FcEditDestroy (e->next);
if (e->expr)
FcExprDestroy (e->expr);
free (e);
@@ -714,7 +728,6 @@ FcTestCreate (FcConfigParse *parse,
{
const FcObjectType *o;
- test->next = 0;
test->kind = kind;
test->qual = qual;
test->object = FcObjectFromName ((const char *) field);
@@ -740,7 +753,6 @@ FcEditCreate (FcConfigParse *parse,
{
const FcObjectType *o;
- e->next = 0;
e->object = object;
e->op = op;
e->expr = expr;
@@ -752,6 +764,34 @@ FcEditCreate (FcConfigParse *parse,
return e;
}
+static FcRule *
+FcRuleCreate (FcRuleType type,
+ void *p)
+{
+ FcRule *r = (FcRule *) malloc (sizeof (FcRule));
+
+ if (!r)
+ return NULL;
+
+ r->next = NULL;
+ r->type = type;
+ switch (type)
+ {
+ case FcRuleTest:
+ r->u.test = (FcTest *) p;
+ break;
+ case FcRuleEdit:
+ r->u.edit = (FcEdit *) p;
+ break;
+ default:
+ free (r);
+ r = NULL;
+ break;
+ }
+
+ return r;
+}
+
static FcVStack *
FcVStackCreateAndPush (FcConfigParse *parse)
{
@@ -1657,9 +1697,9 @@ static void
FcParseAlias (FcConfigParse *parse)
{
FcExpr *family = 0, *accept = 0, *prefer = 0, *def = 0, *new = 0;
- FcEdit *edit = 0, *next;
+ FcEdit *edit = 0;
FcVStack *vstack;
- FcTest *test = NULL;
+ FcRule *rule = NULL, *r;
FcValueBinding binding;
if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding))
@@ -1704,8 +1744,14 @@ FcParseAlias (FcConfigParse *parse)
vstack->tag = FcVStackNone;
break;
case FcVStackTest:
- vstack->u.test->next = test;
- test = vstack->u.test;
+ if (rule)
+ {
+ r = FcRuleCreate (FcRuleTest, vstack->u.test);
+ r->next = rule;
+ rule = r;
+ }
+ else
+ rule = FcRuleCreate (FcRuleTest, vstack->u.test);
vstack->tag = FcVStackNone;
break;
default:
@@ -1723,8 +1769,35 @@ FcParseAlias (FcConfigParse *parse)
FcExprDestroy (accept);
if (def)
FcExprDestroy (def);
+ if (rule)
+ FcRuleDestroy (rule);
return;
}
+ if (!prefer &&
+ !accept &&
+ !def)
+ {
+ FcExprDestroy (family);
+ return;
+ }
+ else
+ {
+ FcTest *t = FcTestCreate (parse, FcMatchPattern,
+ FcQualAny,
+ (FcChar8 *) FC_FAMILY,
+ FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks),
+ family);
+ if (rule)
+ {
+ for (r = rule; r->next; r = r->next);
+ r->next = FcRuleCreate (FcRuleTest, t);
+ r = r->next;
+ }
+ else
+ {
+ r = rule = FcRuleCreate (FcRuleTest, t);
+ }
+ }
if (prefer)
{
edit = FcEditCreate (parse,
@@ -1732,60 +1805,46 @@ FcParseAlias (FcConfigParse *parse)
FcOpPrepend,
prefer,
binding);
- if (edit)
- edit->next = 0;
- else
+ if (!edit)
FcExprDestroy (prefer);
+ else
+ {
+ r->next = FcRuleCreate (FcRuleEdit, edit);
+ r = r->next;
+ }
}
if (accept)
{
- next = edit;
edit = FcEditCreate (parse,
FC_FAMILY_OBJECT,
FcOpAppend,
accept,
binding);
- if (edit)
- edit->next = next;
- else
+ if (!edit)
FcExprDestroy (accept);
+ else
+ {
+ r->next = FcRuleCreate (FcRuleEdit, edit);
+ r = r->next;
+ }
}
if (def)
{
- next = edit;
edit = FcEditCreate (parse,
FC_FAMILY_OBJECT,
FcOpAppendLast,
def,
binding);
- if (edit)
- edit->next = next;
- else
+ if (!edit)
FcExprDestroy (def);
- }
- if (edit)
- {
- FcTest *t = FcTestCreate (parse, FcMatchPattern,
- FcQualAny,
- (FcChar8 *) FC_FAMILY,
- FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks),
- family);
- if (test)
+ else
{
- FcTest *p = test;
-
- while (p->next)
- p = p->next;
- p->next = t;
+ r->next = FcRuleCreate (FcRuleEdit, edit);
+ r = r->next;
}
- else
- test = t;
- if (test)
- if (!FcConfigAddEdit (parse->config, test, edit, FcMatchPattern))
- FcTestDestroy (test);
}
- else
- FcExprDestroy (family);
+ if (!FcConfigAddRule (parse->config, rule, FcMatchPattern))
+ FcRuleDestroy (rule);
}
static FcExpr *
@@ -2386,22 +2445,14 @@ FcParseEdit (FcConfigParse *parse)
FcEditDestroy (edit);
}
-typedef struct FcSubstStack {
- FcTest *test;
- FcEdit *edit;
-} FcSubstStack;
-
static void
FcParseMatch (FcConfigParse *parse)
{
const FcChar8 *kind_name;
FcMatchKind kind;
- FcTest *test = 0;
FcEdit *edit = 0;
FcVStack *vstack;
- FcBool tested = FcFalse;
- FcSubstStack *sstack = NULL;
- int len, pos = 0;
+ FcRule *rule = NULL, *r;
kind_name = FcConfigGetAttribute (parse, "target");
if (!kind_name)
@@ -2420,48 +2471,29 @@ 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) {
case FcVStackTest:
- vstack->u.test->next = test;
- test = vstack->u.test;
+ r = FcRuleCreate (FcRuleTest, vstack->u.test);
+ if (rule)
+ r->next = rule;
+ rule = r;
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;
- if (kind == FcMatchScan && edit->object > FC_MAX_BASE_OBJECT)
+ if (kind == FcMatchScan && vstack->u.edit->object > FC_MAX_BASE_OBJECT)
{
FcConfigMessage (parse, FcSevereError,
"<match target=\"scan\"> cannot edit user-defined object \"%s\"",
FcObjectName(edit->object));
+ break;
}
+ r = FcRuleCreate (FcRuleEdit, vstack->u.edit);
+ if (rule)
+ r->next = rule;
+ rule = r;
+ vstack->tag = FcVStackNone;
break;
default:
FcConfigMessage (parse, FcSevereWarning, "invalid match element");
@@ -2469,22 +2501,8 @@ FcParseMatch (FcConfigParse *parse)
}
FcVStackPopAndDestroy (parse);
}
- if (!FcConfigAddEdit (parse->config, test, edit, kind))
+ if (!FcConfigAddRule (parse->config, rule, 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