]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcxml.c
Whitespace
[fontconfig.git] / src / fcxml.c
index ccc9c194d4463e6803de95f088a99dfe38a41ec1..0952b0b4424f30c967cdc975621945131d214fea 100644 (file)
@@ -13,9 +13,9 @@
  * representations about the suitability of this software for any purpose.  It
  * is provided "as is" without express or implied warranty.
  *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 #endif /* ENABLE_LIBXML2 */
 
 #ifdef _WIN32
+#define _WIN32_WINNT 0x0500
 #define STRICT
 #include <windows.h>
 #undef STRICT
+#include <mbstring.h>
 #endif
 
+static void
+FcExprDestroy (FcExpr *e);
 
 void
 FcTestDestroy (FcTest *test)
@@ -69,125 +73,96 @@ FcTestDestroy (FcTest *test)
     free (test);
 }
 
-FcExpr *
-FcExprCreateInteger (int i)
+static FcExpr *
+FcExprCreateInteger (FcConfig *config, int i)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpInteger;
        e->u.ival = i;
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateDouble (double d)
+static FcExpr *
+FcExprCreateDouble (FcConfig *config, double d)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpDouble;
        e->u.dval = d;
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateString (const FcChar8 *s)
+static FcExpr *
+FcExprCreateString (FcConfig *config, const FcChar8 *s)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpString;
-       e->u.sval = FcStrCopy (s);
+       e->u.sval = FcStrStaticName (s);
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateMatrix (const FcMatrix *m)
+static FcExpr *
+FcExprCreateMatrix (FcConfig *config, const FcMatrix *m)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpMatrix;
        e->u.mval = FcMatrixCopy (m);
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateBool (FcBool b)
+static FcExpr *
+FcExprCreateBool (FcConfig *config, FcBool b)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpBool;
        e->u.bval = b;
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateNil (void)
-{
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
-    if (e)
-    {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
-       e->op = FcOpNil;
-    }
-    return e;
-}
-
-FcExpr *
-FcExprCreateField (const char *field)
+static FcExpr *
+FcExprCreateField (FcConfig *config, const char *field)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpField;
        e->u.object = FcObjectFromName (field);
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateConst (const FcChar8 *constant)
+static FcExpr *
+FcExprCreateConst (FcConfig *config, const FcChar8 *constant)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = FcOpConst;
-       e->u.constant = FcStrCopy (constant);
+       e->u.constant = FcStrStaticName (constant);
     }
     return e;
 }
 
-FcExpr *
-FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right)
+static FcExpr *
+FcExprCreateOp (FcConfig *config, FcExpr *left, FcOp op, FcExpr *right)
 {
-    FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr));
-
+    FcExpr *e = FcConfigAllocExpr (config);
     if (e)
     {
-       FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
        e->op = op;
        e->u.tree.left = left;
        e->u.tree.right = right;
@@ -195,7 +170,7 @@ FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right)
     return e;
 }
 
-void
+static void
 FcExprDestroy (FcExpr *e)
 {
     if (!e)
@@ -206,7 +181,6 @@ FcExprDestroy (FcExpr *e)
     case FcOpDouble:
        break;
     case FcOpString:
-       FcStrFree (e->u.sval);
        break;
     case FcOpMatrix:
        FcMatrixFree (e->u.mval);
@@ -219,7 +193,6 @@ FcExprDestroy (FcExpr *e)
     case FcOpField:
        break;
     case FcOpConst:
-       FcStrFree (e->u.constant);
        break;
     case FcOpAssign:
     case FcOpAssignReplace:
@@ -258,8 +231,8 @@ FcExprDestroy (FcExpr *e)
     case FcOpInvalid:
        break;
     }
-    FcMemFree (FC_MEM_EXPR, sizeof (FcExpr));
-    free (e);
+
+    e->op = FcOpNil;
 }
 
 void
@@ -272,12 +245,6 @@ FcEditDestroy (FcEdit *e)
     free (e);
 }
 
-char *
-FcConfigSaveField (const char *field)
-{
-    return (char *) FcStrCopy ((FcChar8 *) field);
-}
-
 typedef enum _FcElement {
     FcElementNone,
     FcElementFontconfig,
@@ -349,7 +316,7 @@ static const struct {
     { "config",                FcElementConfig },
     { "match",         FcElementMatch },
     { "alias",         FcElementAlias },
-    
+
     { "blank",         FcElementBlank },
     { "rescan",                FcElementRescan },
 
@@ -414,6 +381,7 @@ typedef struct _FcPStack {
     FcElement          element;
     FcChar8            **attr;
     FcStrBuf           str;
+    FcChar8            *attr_buf_static[16];
 } FcPStack;
     
 typedef enum _FcVStackTag {
@@ -469,6 +437,10 @@ typedef struct _FcConfigParse {
     const FcChar8   *name;
     FcConfig       *config;
     XML_Parser     parser;
+    int             pstack_static_used;
+    FcPStack        pstack_static[8];
+    int             vstack_static_used;
+    FcVStack        vstack_static[64];
 } FcConfigParse;
 
 typedef enum _FcConfigSeverity {
@@ -697,186 +669,130 @@ FcEditCreate (FcConfigParse     *parse,
     return e;
 }
 
-static void
-FcVStackPush (FcConfigParse *parse, FcVStack *vstack)
-{
-    vstack->prev = parse->vstack;
-    vstack->pstack = parse->pstack ? parse->pstack->prev : 0;
-    parse->vstack = vstack;
-}
-
 static FcVStack *
-FcVStackCreate (void)
+FcVStackCreateAndPush (FcConfigParse *parse)
 {
     FcVStack    *new;
 
-    new = malloc (sizeof (FcVStack));
-    if (!new)
-       return 0;
-    FcMemAlloc (FC_MEM_VSTACK, sizeof (FcVStack));
+    if (parse->vstack_static_used < sizeof (parse->vstack_static) / sizeof (parse->vstack_static[0]))
+       new = &parse->vstack_static[parse->vstack_static_used++];
+    else
+    {
+       new = malloc (sizeof (FcVStack));
+       if (!new)
+           return 0;
+       FcMemAlloc (FC_MEM_VSTACK, sizeof (FcVStack));
+    }
     new->tag = FcVStackNone;
     new->prev = 0;
-    return new;
-}
 
-static void
-FcVStackDestroy (FcVStack *vstack)
-{
-    FcVStack    *prev;
+    new->prev = parse->vstack;
+    new->pstack = parse->pstack ? parse->pstack->prev : 0;
+    parse->vstack = new;
 
-    for (; vstack; vstack = prev)
-    {
-       prev = vstack->prev;
-       switch (vstack->tag) {
-       case FcVStackNone:
-           break;
-       case FcVStackString:
-       case FcVStackFamily:
-       case FcVStackField:
-       case FcVStackConstant:
-       case FcVStackGlob:
-           FcStrFree (vstack->u.string);
-           break;
-       case FcVStackPattern:
-           FcPatternDestroy (vstack->u.pattern);
-           break;
-       case FcVStackInteger:
-       case FcVStackDouble:
-           break;
-       case FcVStackMatrix:
-           FcMatrixFree (vstack->u.matrix);
-           break;
-       case FcVStackBool:
-           break;
-       case FcVStackTest:
-           FcTestDestroy (vstack->u.test);
-           break;
-       case FcVStackExpr:
-       case FcVStackPrefer:
-       case FcVStackAccept:
-       case FcVStackDefault:
-           FcExprDestroy (vstack->u.expr);
-           break;
-       case FcVStackEdit:
-           FcEditDestroy (vstack->u.edit);
-           break;
-       }
-       FcMemFree (FC_MEM_VSTACK, sizeof (FcVStack));
-       free (vstack);
-    }
+    return new;
 }
 
 static FcBool
 FcVStackPushString (FcConfigParse *parse, FcVStackTag tag, FcChar8 *string)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.string = string;
     vstack->tag = tag;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushInteger (FcConfigParse *parse, int integer)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.integer = integer;
     vstack->tag = FcVStackInteger;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushDouble (FcConfigParse *parse, double _double)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u._double = _double;
     vstack->tag = FcVStackDouble;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix)
 {
-    FcVStack    *vstack = FcVStackCreate ();
-    if (!vstack)
-       return FcFalse;
+    FcVStack    *vstack;
     matrix = FcMatrixCopy (matrix);
     if (!matrix)
-    {
-       FcVStackDestroy (vstack);
        return FcFalse;
-    }
+    vstack = FcVStackCreateAndPush (parse);
+    if (!vstack)
+       return FcFalse;
     vstack->u.matrix = matrix;
     vstack->tag = FcVStackMatrix;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.bool_ = bool_;
     vstack->tag = FcVStackBool;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushTest (FcConfigParse *parse, FcTest *test)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.test = test;
     vstack->tag = FcVStackTest;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushExpr (FcConfigParse *parse, FcVStackTag tag, FcExpr *expr)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.expr = expr;
     vstack->tag = tag;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushEdit (FcConfigParse *parse, FcEdit *edit)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.edit = edit;
     vstack->tag = FcVStackEdit;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
 static FcBool
 FcVStackPushPattern (FcConfigParse *parse, FcPattern *pattern)
 {
-    FcVStack    *vstack = FcVStackCreate ();
+    FcVStack    *vstack = FcVStackCreateAndPush (parse);
     if (!vstack)
        return FcFalse;
     vstack->u.pattern = pattern;
     vstack->tag = FcVStackPattern;
-    FcVStackPush (parse, vstack);
     return FcTrue;
 }
 
@@ -889,28 +805,74 @@ FcVStackFetch (FcConfigParse *parse, int off)
     return vstack;
 }
 
-static void
-FcVStackClear (FcConfigParse *parse)
+static FcVStack *
+FcVStackPeek (FcConfigParse *parse)
 {
-    while (parse->vstack && parse->vstack->pstack == parse->pstack)
-    {
-       FcVStack    *vstack = parse->vstack;
-       parse->vstack = vstack->prev;
-       vstack->prev = 0;
-       FcVStackDestroy (vstack);
-    }
+    FcVStack   *vstack = parse->vstack;
+
+    return vstack && vstack->pstack == parse->pstack ? vstack : 0;
 }
 
-static FcVStack *
-FcVStackPop (FcConfigParse *parse)
+static void
+FcVStackPopAndDestroy (FcConfigParse *parse)
 {
     FcVStack   *vstack = parse->vstack;
     
     if (!vstack || vstack->pstack != parse->pstack)
-       return 0;
+       return;
+
     parse->vstack = vstack->prev;
-    vstack->prev = 0;
-    return vstack;
+
+    switch (vstack->tag) {
+    case FcVStackNone:
+       break;
+    case FcVStackFamily:
+       break;
+    case FcVStackString:
+    case FcVStackField:
+    case FcVStackConstant:
+    case FcVStackGlob:
+       FcStrFree (vstack->u.string);
+       break;
+    case FcVStackPattern:
+       FcPatternDestroy (vstack->u.pattern);
+       break;
+    case FcVStackInteger:
+    case FcVStackDouble:
+       break;
+    case FcVStackMatrix:
+       FcMatrixFree (vstack->u.matrix);
+       break;
+    case FcVStackBool:
+       break;
+    case FcVStackTest:
+       FcTestDestroy (vstack->u.test);
+       break;
+    case FcVStackExpr:
+    case FcVStackPrefer:
+    case FcVStackAccept:
+    case FcVStackDefault:
+       FcExprDestroy (vstack->u.expr);
+       break;
+    case FcVStackEdit:
+       FcEditDestroy (vstack->u.edit);
+       break;
+    }
+
+    if (vstack == &parse->vstack_static[parse->vstack_static_used - 1])
+       parse->vstack_static_used--;
+    else
+    {
+       FcMemFree (FC_MEM_VSTACK, sizeof (FcVStack));
+       free (vstack);
+    }
+}
+
+static void
+FcVStackClear (FcConfigParse *parse)
+{
+    while (FcVStackPeek (parse))
+       FcVStackPopAndDestroy (parse);
 }
 
 static int
@@ -927,7 +889,7 @@ FcVStackElements (FcConfigParse *parse)
 }
 
 static FcChar8 **
-FcConfigSaveAttr (const XML_Char **attr)
+FcConfigSaveAttr (const XML_Char **attr, FcChar8 **buf, int size_bytes)
 {
     int                slen;
     int                i;
@@ -941,13 +903,19 @@ FcConfigSaveAttr (const XML_Char **attr)
        slen += strlen ((char *) attr[i]) + 1;
     if (i == 0)
        return 0;
-    new = malloc ((i + 1) * sizeof (FcChar8 *) + slen);
-    if (!new)
+    slen += (i + 1) * sizeof (FcChar8 *);
+    if (slen <= size_bytes)
+       new = buf;
+    else
     {
-       FcConfigMessage (0, FcSevereError, "out of memory");
-       return 0;
+       new = malloc (slen);
+       if (!new)
+       {
+           FcConfigMessage (0, FcSevereError, "out of memory");
+           return 0;
+       }
+       FcMemAlloc (FC_MEM_ATTR, 1);    /* size is too expensive */
     }
-    FcMemAlloc (FC_MEM_ATTR, 1);    /* size is too expensive */
     s = (FcChar8 *) (new + (i + 1));
     for (i = 0; attr[i]; i++)
     {
@@ -962,14 +930,21 @@ FcConfigSaveAttr (const XML_Char **attr)
 static FcBool
 FcPStackPush (FcConfigParse *parse, FcElement element, const XML_Char **attr)
 {
-    FcPStack   *new = malloc (sizeof (FcPStack));
+    FcPStack   *new;
+
+    if (parse->pstack_static_used < sizeof (parse->pstack_static) / sizeof (parse->pstack_static[0]))
+       new = &parse->pstack_static[parse->pstack_static_used++];
+    else
+    {
+       new = malloc (sizeof (FcPStack));
+       if (!new)
+           return FcFalse;
+       FcMemAlloc (FC_MEM_PSTACK, sizeof (FcPStack));
+    }
 
-    if (!new)
-       return FcFalse;
-    FcMemAlloc (FC_MEM_PSTACK, sizeof (FcPStack));
     new->prev = parse->pstack;
     new->element = element;
-    new->attr = FcConfigSaveAttr (attr);
+    new->attr = FcConfigSaveAttr (attr, new->attr_buf_static, sizeof (new->attr_buf_static));
     FcStrBufInit (&new->str, 0, 0);
     parse->pstack = new;
     return FcTrue;
@@ -989,13 +964,19 @@ FcPStackPop (FcConfigParse *parse)
     old = parse->pstack;
     parse->pstack = old->prev;
     FcStrBufDestroy (&old->str);
-    if (old->attr)
+    if (old->attr && old->attr != old->attr_buf_static)
     {
        FcMemFree (FC_MEM_ATTR, 1); /* size is to expensive */
        free (old->attr);
     }
-    FcMemFree (FC_MEM_PSTACK, sizeof (FcPStack));
-    free (old);
+
+    if (old == &parse->pstack_static[parse->pstack_static_used - 1])
+       parse->pstack_static_used--;
+    else
+    {
+       FcMemFree (FC_MEM_PSTACK, sizeof (FcPStack));
+       free (old);
+    }
     return FcTrue;
 }
 
@@ -1003,7 +984,9 @@ static FcBool
 FcConfigInit (FcConfigParse *parse, const FcChar8 *name, FcConfig *config, XML_Parser parser)
 {
     parse->pstack = 0;
+    parse->pstack_static_used = 0;
     parse->vstack = 0;
+    parse->vstack_static_used = 0;
     parse->error = FcFalse;
     parse->name = name;
     parse->config = config;
@@ -1227,7 +1210,7 @@ FcParseMatrix (FcConfigParse *parse)
     enum { m_done, m_xx, m_xy, m_yx, m_yy } matrix_state = m_yy;
     FcMatrix   m;
     
-    while ((vstack = FcVStackPop (parse)))
+    while ((vstack = FcVStackPeek (parse)))
     {
        double  v;
        switch (vstack->tag) {
@@ -1249,7 +1232,7 @@ FcParseMatrix (FcConfigParse *parse)
        case m_yy: m.yy = v; break;
        default: break;
        }
-       FcVStackDestroy (vstack);
+       FcVStackPopAndDestroy (parse);
        matrix_state--;
     }
     if (matrix_state != m_done)
@@ -1319,20 +1302,20 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag)
     FcVStack   *vstack;
     FcExpr     *left, *expr = 0, *new;
 
-    while ((vstack = FcVStackPop (parse)))
+    while ((vstack = FcVStackPeek (parse)))
     {
        if (vstack->tag != FcVStackFamily)
        {
            FcConfigMessage (parse, FcSevereWarning, "non-family");
-           FcVStackDestroy (vstack);
+           FcVStackPopAndDestroy (parse);
            continue;
        }
        left = vstack->u.expr;
        vstack->tag = FcVStackNone;
-       FcVStackDestroy (vstack);
+       FcVStackPopAndDestroy (parse);
        if (expr)
        {
-           new = FcExprCreateOp (left, FcOpComma, expr);
+           new = FcExprCreateOp (parse->config, left, FcOpComma, expr);
            if (!new)
            {
                FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -1369,7 +1352,7 @@ FcParseFamily (FcConfigParse *parse)
        FcConfigMessage (parse, FcSevereError, "out of memory");
        return;
     }
-    expr = FcExprCreateString (s);
+    expr = FcExprCreateString (parse->config, s);
     FcStrBufDestroy (&parse->pstack->str);
     if (expr)
        FcVStackPushExpr (parse, FcVStackFamily, expr);
@@ -1386,13 +1369,13 @@ FcParseAlias (FcConfigParse *parse)
 
     if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding))
        return;
-    while ((vstack = FcVStackPop (parse))) 
+    while ((vstack = FcVStackPeek (parse)))
     {
        switch (vstack->tag) {
        case FcVStackFamily:
            if (family)
            {
-               new = FcExprCreateOp (vstack->u.expr, FcOpComma, family);
+               new = FcExprCreateOp (parse->config, vstack->u.expr, FcOpComma, family);
                if (!new)
                    FcConfigMessage (parse, FcSevereError, "out of memory");
                else
@@ -1428,7 +1411,7 @@ FcParseAlias (FcConfigParse *parse)
            FcConfigMessage (parse, FcSevereWarning, "bad alias");
            break;
        }
-       FcVStackDestroy (vstack);
+       FcVStackPopAndDestroy (parse);
     }
     if (!family)
     {
@@ -1497,7 +1480,7 @@ FcParseAlias (FcConfigParse *parse)
 static FcExpr *
 FcPopExpr (FcConfigParse *parse)
 {
-    FcVStack   *vstack = FcVStackPop (parse);
+    FcVStack   *vstack = FcVStackPeek (parse);
     FcExpr     *expr = 0;
     if (!vstack)
        return 0;
@@ -1506,13 +1489,13 @@ FcPopExpr (FcConfigParse *parse)
        break;
     case FcVStackString:
     case FcVStackFamily:
-       expr = FcExprCreateString (vstack->u.string);
+       expr = FcExprCreateString (parse->config, vstack->u.string);
        break;
     case FcVStackField:
-       expr = FcExprCreateField ((char *) vstack->u.string);
+       expr = FcExprCreateField (parse->config, (char *) vstack->u.string);
        break;
     case FcVStackConstant:
-       expr = FcExprCreateConst (vstack->u.string);
+       expr = FcExprCreateConst (parse->config, vstack->u.string);
        break;
     case FcVStackGlob:
        /* XXX: What's the correct action here? (CDW) */
@@ -1524,16 +1507,16 @@ FcPopExpr (FcConfigParse *parse)
        vstack->tag = FcVStackNone;
        break;
     case FcVStackInteger:
-       expr = FcExprCreateInteger (vstack->u.integer);
+       expr = FcExprCreateInteger (parse->config, vstack->u.integer);
        break;
     case FcVStackDouble:
-       expr = FcExprCreateDouble (vstack->u._double);
+       expr = FcExprCreateDouble (parse->config, vstack->u._double);
        break;
     case FcVStackMatrix:
-       expr = FcExprCreateMatrix (vstack->u.matrix);
+       expr = FcExprCreateMatrix (parse->config, vstack->u.matrix);
        break;
     case FcVStackBool:
-       expr = FcExprCreateBool (vstack->u.bool_);
+       expr = FcExprCreateBool (parse->config, vstack->u.bool_);
        break;
     case FcVStackTest:
        break;
@@ -1546,7 +1529,7 @@ FcPopExpr (FcConfigParse *parse)
     default:
        break;
     }
-    FcVStackDestroy (vstack);
+    FcVStackPopAndDestroy (parse);
     return expr;
 }
 
@@ -1568,7 +1551,7 @@ FcPopBinary (FcConfigParse *parse, FcOp op)
     {
        if (expr)
        {
-           new = FcExprCreateOp (left, op, expr);
+           new = FcExprCreateOp (parse->config, left, op, expr);
            if (!new)
            {
                FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -1604,7 +1587,7 @@ FcPopUnary (FcConfigParse *parse, FcOp op)
 
     if ((operand = FcPopExpr (parse)))
     {
-       new = FcExprCreateOp (operand, op, 0);
+       new = FcExprCreateOp (parse->config, operand, op, 0);
        if (!new)
        {
            FcExprDestroy (operand);
@@ -1849,7 +1832,7 @@ FcParseMatch (FcConfigParse *parse)
            return;
        }
     }
-    while ((vstack = FcVStackPop (parse)))
+    while ((vstack = FcVStackPeek (parse)))
     {
        switch (vstack->tag) {
        case FcVStackTest:
@@ -1872,7 +1855,7 @@ FcParseMatch (FcConfigParse *parse)
            FcConfigMessage (parse, FcSevereWarning, "invalid match element");
            break;
        }
-       FcVStackDestroy (vstack);
+       FcVStackPopAndDestroy (parse);
     }
     if (!FcConfigAddEdit (parse->config, test, edit, kind))
        FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -1883,7 +1866,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
 {
     FcVStack   *vstack;
 
-    while ((vstack = FcVStackPop (parse)))
+    while ((vstack = FcVStackPeek (parse)))
     {
        switch (vstack->tag) {
        case FcVStackGlob:
@@ -1908,7 +1891,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
            FcConfigMessage (parse, FcSevereWarning, "bad font selector");
            break;
        }
-       FcVStackDestroy (vstack);
+       FcVStackPopAndDestroy (parse);
     }
 }
 
@@ -1916,7 +1899,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
 static FcValue
 FcPopValue (FcConfigParse *parse)
 {
-    FcVStack   *vstack = FcVStackPop (parse);
+    FcVStack   *vstack = FcVStackPeek (parse);
     FcValue    value;
     
     value.type = FcTypeVoid;
@@ -1926,7 +1909,7 @@ FcPopValue (FcConfigParse *parse)
     
     switch (vstack->tag) {
     case FcVStackString:
-       value.u.s = FcStrCopy (vstack->u.string);
+       value.u.s = FcStrStaticName (vstack->u.string);
        if (value.u.s)
            value.type = FcTypeString;
        break;
@@ -1956,7 +1939,7 @@ FcPopValue (FcConfigParse *parse)
                         vstack->tag);
        break;
     }
-    FcVStackDestroy (vstack);
+    FcVStackPopAndDestroy (parse);
     
     return value;
 }
@@ -2011,7 +1994,7 @@ FcParsePattern (FcConfigParse *parse)
        return;
     }
        
-    while ((vstack = FcVStackPop (parse)))
+    while ((vstack = FcVStackPeek (parse)))
     {
        switch (vstack->tag) {
        case FcVStackPattern:
@@ -2026,7 +2009,7 @@ FcParsePattern (FcConfigParse *parse)
            FcConfigMessage (parse, FcSevereWarning, "unknown pattern element");
            break;
        }
-       FcVStackDestroy (vstack);
+       FcVStackPopAndDestroy (parse);
     }
 
     FcVStackPushPattern (parse, pattern);
@@ -2037,7 +2020,10 @@ FcEndElement(void *userData, const XML_Char *name)
 {
     FcConfigParse   *parse = userData;
     FcChar8        *data;
-    
+#ifdef _WIN32
+    FcChar8         buffer[1000];
+#endif
+
     if (!parse->pstack)
        return;
     switch (parse->pstack->element) {
@@ -2056,61 +2042,47 @@ FcEndElement(void *userData, const XML_Char *name)
        if (strcmp (data, "CUSTOMFONTDIR") == 0)
        {
                char *p;
-               FcStrFree (data);
-               data = malloc (1000);
-               if (!data)
-               {
-                       FcConfigMessage (parse, FcSevereError, "out of memory");
-                       break;
-               }
-               FcMemAlloc (FC_MEM_STRING, 1000);
-               if(!GetModuleFileName(NULL, data, 1000))
+               data = buffer;
+               if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20))
                {
                        FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
-                       FcStrFree (data);
                        break;
                }
-               p = strrchr (data, '\\');
+               /*
+                * Must use the multi-byte aware function to search
+                * for backslash because East Asian double-byte code
+                * pages have characters with backslash as the second
+                * byte.
+                */
+               p = _mbsrchr (data, '\\');
                if (p) *p = '\0';
                strcat (data, "\\fonts");
        }
        else if (strcmp (data, "APPSHAREFONTDIR") == 0)
        {
                char *p;
-               FcStrFree (data);
-               data = malloc (1000);
-               if (!data)
-               {
-                       FcConfigMessage (parse, FcSevereError, "out of memory");
-                       break;
-               }
-               FcMemAlloc (FC_MEM_STRING, 1000);
-               if(!GetModuleFileName(NULL, data, 1000))
+               data = buffer;
+               if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20))
                {
                        FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
-                       FcStrFree (data);
                        break;
                }
-               p = strrchr (data, '\\');
+               p = _mbsrchr (data, '\\');
                if (p) *p = '\0';
                strcat (data, "\\..\\share\\fonts");
        }
        else 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)
+           data = buffer;
+#if _WIN32_WINNT >= 0x0500
+           rc = GetSystemWindowsDirectory (buffer, sizeof (buffer) - 20);
+#else
+           rc = GetWindowsDirectory (buffer, sizeof (buffer) - 20);
+#endif
+           if (rc == 0 || rc > sizeof (buffer) - 20)
            {
-               FcConfigMessage (parse, FcSevereError, "GetWindowsDirectory failed");
-               FcStrFree (data);
+               FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
                break;
            }
            if (data [strlen (data) - 1] != '\\')
@@ -2149,7 +2121,7 @@ FcEndElement(void *userData, const XML_Char *name)
            rc = GetTempPath (800, data);
            if (rc == 0 || rc > 800)
            {
-               FcConfigMessage (parse, FcSevereError, "GetWindowsDirectory failed");
+               FcConfigMessage (parse, FcSevereError, "GetTempPath failed");
                FcStrFree (data);
                break;
            }