/*
- * $XFree86: xc/lib/fontconfig/src/fcxml.c,v 1.19 2002/08/19 19:32:05 keithp Exp $
+ * $RCSId: xc/lib/fontconfig/src/fcxml.c,v 1.21 2002/08/22 18:53:22 keithp Exp $
*
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright © 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#include <expat.h>
#endif
+#ifdef _WIN32
+#define STRICT
+#include <windows.h>
+#undef STRICT
+#endif
+
FcTest *
FcTestCreate (FcMatchKind kind,
FcQual qual,
if (test)
{
+ FcMemAlloc (FC_MEM_TEST, sizeof (FcTest));
test->next = 0;
test->kind = kind;
test->qual = qual;
FcTestDestroy (test->next);
FcExprDestroy (test->expr);
FcStrFree ((FcChar8 *) test->field);
+ FcMemFree (FC_MEM_TEST, sizeof (FcTest));
free (test);
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpInteger;
e->u.ival = i;
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpDouble;
e->u.dval = d;
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpString;
e->u.sval = FcStrCopy (s);
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpMatrix;
e->u.mval = FcMatrixCopy (m);
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpBool;
e->u.bval = b;
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpNil;
}
return e;
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpField;
e->u.field = (char *) FcStrCopy ((FcChar8 *) field);
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = FcOpConst;
e->u.constant = FcStrCopy (constant);
}
if (e)
{
+ FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
e->op = op;
e->u.tree.left = left;
e->u.tree.right = right;
void
FcExprDestroy (FcExpr *e)
{
+ if (!e)
+ return;
switch (e->op) {
case FcOpInteger:
break;
case FcOpOr:
case FcOpAnd:
case FcOpEqual:
- case FcOpContains:
case FcOpNotEqual:
case FcOpLess:
case FcOpLessEqual:
case FcOpMore:
case FcOpMoreEqual:
+ case FcOpContains:
+ case FcOpListing:
+ case FcOpNotContains:
case FcOpPlus:
case FcOpMinus:
case FcOpTimes:
FcExprDestroy (e->u.tree.right);
/* fall through */
case FcOpNot:
+ case FcOpFloor:
+ case FcOpCeil:
+ case FcOpRound:
+ case FcOpTrunc:
FcExprDestroy (e->u.tree.left);
break;
case FcOpNil:
case FcOpInvalid:
break;
}
+ FcMemFree (FC_MEM_EXPR, sizeof (FcExpr));
free (e);
}
FcStrFree ((FcChar8 *) e->field);
if (e->expr)
FcExprDestroy (e->expr);
+ free (e);
}
char *
FcElementDefault,
FcElementFamily,
+ FcElementSelectfont,
+ FcElementAcceptfont,
+ FcElementRejectfont,
+ FcElementGlob,
+
FcElementTest,
FcElementEdit,
FcElementInt,
FcElementLessEq,
FcElementMore,
FcElementMoreEq,
+ FcElementContains,
+ FcElementNotContains,
FcElementPlus,
FcElementMinus,
FcElementTimes,
FcElementDivide,
FcElementNot,
FcElementIf,
+ FcElementFloor,
+ FcElementCeil,
+ FcElementRound,
+ FcElementTrunc,
FcElementUnknown
} FcElement;
{ "default", FcElementDefault },
{ "family", FcElementFamily },
+ { "selectfont", FcElementSelectfont },
+ { "acceptfont", FcElementAcceptfont },
+ { "rejectfont", FcElementRejectfont },
+ { "glob", FcElementGlob },
+
{ "test", FcElementTest },
{ "edit", FcElementEdit },
{ "int", FcElementInt },
{ "less_eq", FcElementLessEq },
{ "more", FcElementMore },
{ "more_eq", FcElementMoreEq },
+ { "contains", FcElementContains },
+ { "not_contains",FcElementNotContains },
{ "plus", FcElementPlus },
{ "minus", FcElementMinus },
{ "times", FcElementTimes },
{ "divide", FcElementDivide },
{ "not", FcElementNot },
{ "if", FcElementIf },
+ { "floor", FcElementFloor },
+ { "ceil", FcElementCeil },
+ { "round", FcElementRound },
+ { "trunc", FcElementTrunc },
{ 0, 0 }
};
FcVStackFamily,
FcVStackField,
FcVStackConstant,
+ FcVStackGlob,
FcVStackPrefer,
FcVStackAccept,
new = malloc (sizeof (FcVStack));
if (!new)
return 0;
+ FcMemAlloc (FC_MEM_VSTACK, sizeof (FcVStack));
new->tag = FcVStackNone;
new->prev = 0;
return new;
case FcVStackFamily:
case FcVStackField:
case FcVStackConstant:
+ case FcVStackGlob:
FcStrFree (vstack->u.string);
break;
case FcVStackInteger:
FcEditDestroy (vstack->u.edit);
break;
}
+ FcMemFree (FC_MEM_VSTACK, sizeof (FcVStack));
free (vstack);
}
}
new = malloc ((i + 1) * sizeof (FcChar8 *) + slen);
if (!new)
return 0;
+ FcMemAlloc (FC_MEM_ATTR, 1); /* size is too expensive */
s = (FcChar8 *) (new + (i + 1));
for (i = 0; attr[i]; i++)
{
if (!new)
return FcFalse;
+ FcMemAlloc (FC_MEM_PSTACK, sizeof (FcPStack));
new->prev = parse->pstack;
new->element = element;
if (attr)
parse->pstack = old->prev;
FcStrBufDestroy (&old->str);
if (old->attr)
+ {
+ FcMemFree (FC_MEM_ATTR, 1); /* size is to expensive */
free (old->attr);
+ }
+ FcMemFree (FC_MEM_PSTACK, sizeof (FcPStack));
free (old);
return FcTrue;
}
buf_end = 0;
v = strtod (buf, &buf_end);
if (buf_end)
- buf_end = s + (buf_end - buf);
+ buf_end = s + (buf_end - buf) + 1 - dlen;
if (end)
*end = buf_end;
}
case FcVStackConstant:
expr = FcExprCreateConst (vstack->u.string);
break;
+ case FcVStackGlob:
+ /* XXX: What's the correct action here? (CDW) */
+ break;
case FcVStackPrefer:
case FcVStackAccept:
case FcVStackDefault:
return expr;
}
+/*
+ * This builds a tree of binary operations. Note
+ * that every operator is defined so that if only
+ * a single operand is contained, the value of the
+ * whole expression is the value of the operand.
+ *
+ * This code reduces in that case to returning that
+ * operand.
+ */
static FcExpr *
-FcPopExprs (FcConfigParse *parse, FcOp op)
+FcPopBinary (FcConfigParse *parse, FcOp op)
{
FcExpr *left, *expr = 0, *new;
}
static void
-FcParseExpr (FcConfigParse *parse, FcOp op)
+FcParseBinary (FcConfigParse *parse, FcOp op)
+{
+ FcExpr *expr = FcPopBinary (parse, op);
+ if (expr)
+ FcVStackPushExpr (parse, FcVStackExpr, expr);
+}
+
+/*
+ * This builds a a unary operator, it consumes only
+ * a single operand
+ */
+
+static FcExpr *
+FcPopUnary (FcConfigParse *parse, FcOp op)
+{
+ FcExpr *operand, *new = 0;
+
+ if ((operand = FcPopExpr (parse)))
+ {
+ new = FcExprCreateOp (operand, op, 0);
+ if (!new)
+ {
+ FcExprDestroy (operand);
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ }
+ }
+ return new;
+}
+
+static void
+FcParseUnary (FcConfigParse *parse, FcOp op)
{
- FcExpr *expr = FcPopExprs (parse, op);
+ FcExpr *expr = FcPopUnary (parse, op);
if (expr)
FcVStackPushExpr (parse, FcVStackExpr, expr);
}
ignore_missing = FcTrue;
if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
parse->error = FcTrue;
- free (s);
+ FcStrFree (s);
}
typedef struct _FcOpMap {
{ "less", FcOpLess },
{ "less_eq", FcOpLessEqual },
{ "more", FcOpMore },
- { "more_eq", FcOpMoreEqual }
+ { "more_eq", FcOpMoreEqual },
+ { "contains", FcOpContains },
+ { "not_contains", FcOpNotContains }
};
#define NUM_COMPARE_OPS (sizeof fcCompareOps / sizeof fcCompareOps[0])
return;
}
}
- expr = FcPopExprs (parse, FcOpComma);
+ expr = FcPopBinary (parse, FcOpComma);
if (!expr)
{
FcConfigMessage (parse, FcSevereWarning, "missing test expression");
binding = FcValueBindingWeak;
else if (!strcmp ((char *) binding_string, "strong"))
binding = FcValueBindingStrong;
+ else if (!strcmp ((char *) binding_string, "same"))
+ binding = FcValueBindingSame;
else
{
FcConfigMessage (parse, FcSevereWarning, "invalid edit binding \"%s\"", binding_string);
return;
}
}
- expr = FcPopExprs (parse, FcOpComma);
+ expr = FcPopBinary (parse, FcOpComma);
edit = FcEditCreate ((char *) FcStrCopy (name), mode, expr, binding);
if (!edit)
{
FcConfigMessage (parse, FcSevereError, "out of memory");
}
+static void
+FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
+{
+ FcVStack *vstack;
+
+ while ((vstack = FcVStackPop (parse)))
+ {
+ switch (vstack->tag) {
+ case FcVStackGlob:
+ if (!FcConfigGlobAdd (parse->config,
+ vstack->u.string,
+ element == FcElementAcceptfont))
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ }
+ break;
+ default:
+ FcConfigMessage (parse, FcSevereWarning, "bad font selector");
+ break;
+ }
+ FcVStackDestroy (vstack);
+ }
+}
+
static void
FcEndElement(void *userData, const XML_Char *name)
{
FcConfigMessage (parse, FcSevereError, "out of memory");
break;
}
- if (!FcConfigAddDir (parse->config, data))
- FcConfigMessage (parse, FcSevereError, "out of memory");
- free (data);
+#ifdef _WIN32
+ if (strcmp (data, "WINDOWSFONTDIR") == 0)
+ {
+ int rc;
+ FcStrFree (data);
+ data = malloc (1000);
+ if (!data)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ break;
+ }
+ FcMemAlloc (FC_MEM_STRING, 1000);
+ rc = GetWindowsDirectory (data, 800);
+ if (rc == 0 || rc > 800)
+ {
+ FcConfigMessage (parse, FcSevereError, "GetWindowsDirectory failed");
+ FcStrFree (data);
+ break;
+ }
+ if (data [strlen (data) - 1] != '\\')
+ strcat (data, "\\");
+ strcat (data, "fonts");
+ }
+#endif
+ if (!FcStrUsesHome (data) || FcConfigHome ())
+ {
+ if (!FcConfigAddDir (parse->config, data))
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ }
+ FcStrFree (data);
break;
case FcElementCache:
data = FcStrBufDone (&parse->pstack->str);
FcConfigMessage (parse, FcSevereError, "out of memory");
break;
}
- if (!FcConfigSetCache (parse->config, data))
- FcConfigMessage (parse, FcSevereError, "out of memory");
- free (data);
+ if (!FcStrUsesHome (data) || FcConfigHome ())
+ {
+ if (!FcConfigSetCache (parse->config, data))
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ }
+ FcStrFree (data);
break;
case FcElementInclude:
FcParseInclude (parse);
case FcElementCharset:
/* FcParseCharset (parse); */
break;
-
+ case FcElementSelectfont:
+ break;
+ case FcElementAcceptfont:
+ case FcElementRejectfont:
+ FcParseAcceptRejectFont (parse, parse->pstack->element);
+ break;
+ case FcElementGlob:
+ FcParseString (parse, FcVStackGlob);
+ break;
case FcElementName:
FcParseString (parse, FcVStackField);
break;
FcParseString (parse, FcVStackConstant);
break;
case FcElementOr:
- FcParseExpr (parse, FcOpOr);
+ FcParseBinary (parse, FcOpOr);
break;
case FcElementAnd:
- FcParseExpr (parse, FcOpAnd);
+ FcParseBinary (parse, FcOpAnd);
break;
case FcElementEq:
- FcParseExpr (parse, FcOpEqual);
+ FcParseBinary (parse, FcOpEqual);
break;
case FcElementNotEq:
- FcParseExpr (parse, FcOpNotEqual);
+ FcParseBinary (parse, FcOpNotEqual);
break;
case FcElementLess:
- FcParseExpr (parse, FcOpLess);
+ FcParseBinary (parse, FcOpLess);
break;
case FcElementLessEq:
- FcParseExpr (parse, FcOpLessEqual);
+ FcParseBinary (parse, FcOpLessEqual);
break;
case FcElementMore:
- FcParseExpr (parse, FcOpMore);
+ FcParseBinary (parse, FcOpMore);
break;
case FcElementMoreEq:
- FcParseExpr (parse, FcOpMoreEqual);
+ FcParseBinary (parse, FcOpMoreEqual);
+ break;
+ case FcElementContains:
+ FcParseBinary (parse, FcOpContains);
+ break;
+ case FcElementNotContains:
+ FcParseBinary (parse, FcOpNotContains);
break;
case FcElementPlus:
- FcParseExpr (parse, FcOpPlus);
+ FcParseBinary (parse, FcOpPlus);
break;
case FcElementMinus:
- FcParseExpr (parse, FcOpMinus);
+ FcParseBinary (parse, FcOpMinus);
break;
case FcElementTimes:
- FcParseExpr (parse, FcOpTimes);
+ FcParseBinary (parse, FcOpTimes);
break;
case FcElementDivide:
- FcParseExpr (parse, FcOpDivide);
+ FcParseBinary (parse, FcOpDivide);
break;
case FcElementNot:
- FcParseExpr (parse, FcOpNot);
+ FcParseUnary (parse, FcOpNot);
break;
case FcElementIf:
- FcParseExpr (parse, FcOpQuest);
+ FcParseBinary (parse, FcOpQuest);
+ break;
+ case FcElementFloor:
+ FcParseUnary (parse, FcOpFloor);
+ break;
+ case FcElementCeil:
+ FcParseUnary (parse, FcOpCeil);
+ break;
+ case FcElementRound:
+ FcParseUnary (parse, FcOpRound);
+ break;
+ case FcElementTrunc:
+ FcParseUnary (parse, FcOpTrunc);
break;
case FcElementUnknown:
break;
goto bail0;
if (!FcStrSetAdd (config->configFiles, filename))
+ {
+ FcStrFree (filename);
goto bail0;
+ }
f = fopen ((char *) filename, "r");
- free (filename);
+ FcStrFree (filename);
if (!f)
goto bail0;