]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcxml.c
[fcxml] Embed 8 static FcPStack objects in FcConfigParse
[fontconfig.git] / src / fcxml.c
index 14da71376f958a9a89ca0b9aa3dff12a3592885a..e6d16f3d4812b57137ce7be3b3e65b942e4ae155 100644 (file)
@@ -469,6 +469,8 @@ typedef struct _FcConfigParse {
     const FcChar8   *name;
     FcConfig       *config;
     XML_Parser     parser;
+    int             pstack_static_used;
+    FcPStack        pstack_static[8];
 } FcConfigParse;
 
 typedef enum _FcConfigSeverity {
@@ -939,9 +941,14 @@ FcConfigSaveAttr (const XML_Char **attr)
     slen = 0;
     for (i = 0; attr[i]; i++)
        slen += strlen ((char *) attr[i]) + 1;
+    if (i == 0)
+       return 0;
     new = malloc ((i + 1) * sizeof (FcChar8 *) + slen);
     if (!new)
+    {
+       FcConfigMessage (0, FcSevereError, "out of memory");
        return 0;
+    }
     FcMemAlloc (FC_MEM_ATTR, 1);    /* size is too expensive */
     s = (FcChar8 *) (new + (i + 1));
     for (i = 0; attr[i]; i++)
@@ -957,26 +964,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 (!new)
-       return FcFalse;
-    FcMemAlloc (FC_MEM_PSTACK, sizeof (FcPStack));
-    new->prev = parse->pstack;
-    new->element = element;
-    if (attr)
+    if (parse->pstack_static_used < sizeof (parse->pstack_static) / sizeof (parse->pstack_static[0]))
+       new = &parse->pstack_static[parse->pstack_static_used++];
+    else
     {
-       new->attr = FcConfigSaveAttr (attr);
-       if (!new->attr)
-       {
-           FcConfigMessage (parse, FcSevereError, "out of memory");
-           FcMemFree (FC_MEM_PSTACK, sizeof (FcPStack));
-           free (new);
+       new = malloc (sizeof (FcPStack));
+       if (!new)
            return FcFalse;
-       }
+       FcMemAlloc (FC_MEM_PSTACK, sizeof (FcPStack));
     }
-    else
-       new->attr = 0;
+
+    new->prev = parse->pstack;
+    new->element = element;
+    new->attr = FcConfigSaveAttr (attr);
     FcStrBufInit (&new->str, 0, 0);
     parse->pstack = new;
     return FcTrue;
@@ -1001,8 +1003,14 @@ FcPStackPop (FcConfigParse *parse)
        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;
 }
 
@@ -1010,6 +1018,7 @@ 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->error = FcFalse;
     parse->name = name;
@@ -1114,7 +1123,7 @@ FcParseInt (FcConfigParse *parse)
     
     if (!parse->pstack)
        return;
-    s = FcStrBufDone (&parse->pstack->str);
+    s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
        FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -1126,7 +1135,7 @@ FcParseInt (FcConfigParse *parse)
        FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid integer", s);
     else
        FcVStackPushInteger (parse, l);
-    FcStrFree (s);
+    FcStrBufDestroy (&parse->pstack->str);
 }
 
 /*
@@ -1195,7 +1204,7 @@ FcParseDouble (FcConfigParse *parse)
     
     if (!parse->pstack)
        return;
-    s = FcStrBufDone (&parse->pstack->str);
+    s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
        FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -1207,7 +1216,7 @@ FcParseDouble (FcConfigParse *parse)
        FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid double", s);
     else
        FcVStackPushDouble (parse, d);
-    FcStrFree (s);
+    FcStrBufDestroy (&parse->pstack->str);
 }
 
 static void
@@ -1283,14 +1292,14 @@ FcParseBool (FcConfigParse *parse)
 
     if (!parse->pstack)
        return;
-    s = FcStrBufDone (&parse->pstack->str);
+    s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
        FcConfigMessage (parse, FcSevereError, "out of memory");
        return;
     }
     FcVStackPushBool (parse, FcConfigLexBool (parse, s));
-    FcStrFree (s);
+    FcStrBufDestroy (&parse->pstack->str);
 }
 
 static FcBool
@@ -1370,14 +1379,14 @@ FcParseFamily (FcConfigParse *parse)
 
     if (!parse->pstack)
        return;
-    s = FcStrBufDone (&parse->pstack->str);
+    s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
        FcConfigMessage (parse, FcSevereError, "out of memory");
        return;
     }
     expr = FcExprCreateString (s);
-    FcStrFree (s);
+    FcStrBufDestroy (&parse->pstack->str);
     if (expr)
        FcVStackPushExpr (parse, FcVStackFamily, expr);
 }
@@ -1636,7 +1645,7 @@ FcParseInclude (FcConfigParse *parse)
     const FcChar8   *i;
     FcBool         ignore_missing = FcFalse;
     
-    s = FcStrBufDone (&parse->pstack->str);
+    s = FcStrBufDoneStatic (&parse->pstack->str);
     if (!s)
     {
        FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -1647,7 +1656,7 @@ FcParseInclude (FcConfigParse *parse)
        ignore_missing = FcTrue;
     if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
        parse->error = FcTrue;
-    FcStrFree (s);
+    FcStrBufDestroy (&parse->pstack->str);
 }
 
 typedef struct _FcOpMap {
@@ -2053,7 +2062,7 @@ FcEndElement(void *userData, const XML_Char *name)
     case FcElementFontconfig:
        break;
     case FcElementDir:
-       data = FcStrBufDone (&parse->pstack->str);
+       data = FcStrBufDoneStatic (&parse->pstack->str);
        if (!data)
        {
            FcConfigMessage (parse, FcSevereError, "out of memory");
@@ -2132,7 +2141,7 @@ FcEndElement(void *userData, const XML_Char *name)
            if (!FcConfigAddDir (parse->config, data))
                FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data);
        }
-       FcStrFree (data);
+       FcStrBufDestroy (&parse->pstack->str);
        break;
     case FcElementCacheDir:
        data = FcStrBufDone (&parse->pstack->str);
@@ -2174,14 +2183,14 @@ FcEndElement(void *userData, const XML_Char *name)
        break;
        
     case FcElementCache:
-       data = FcStrBufDone (&parse->pstack->str);
+       data = FcStrBufDoneStatic (&parse->pstack->str);
        if (!data)
        {
            FcConfigMessage (parse, FcSevereError, "out of memory");
            break;
        }
        /* discard this data; no longer used */
-       FcStrFree (data);
+       FcStrBufDestroy (&parse->pstack->str);
        break;
     case FcElementInclude:
        FcParseInclude (parse);