X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcxml.c;h=23591d25f20adf78f17eebba0971980a404e587b;hb=a96ecbfa20fbc66fad3847b1d2bc6fb3cd712c91;hp=ccc9c194d4463e6803de95f088a99dfe38a41ec1;hpb=532d8a1dbc2baebc2603d091952a640b954b6f71;p=fontconfig.git diff --git a/src/fcxml.c b/src/fcxml.c index ccc9c19..23591d2 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -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 @@ -69,14 +69,23 @@ FcTestDestroy (FcTest *test) free (test); } -FcExpr * -FcExprCreateInteger (int i) +static FcExpr * +FcExprAlloc (void) { FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); + if (e) + FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); + + return e; +} + +FcExpr * +FcExprCreateInteger (int i) +{ + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpInteger; e->u.ival = i; } @@ -86,11 +95,9 @@ FcExprCreateInteger (int i) FcExpr * FcExprCreateDouble (double d) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpDouble; e->u.dval = d; } @@ -100,11 +107,9 @@ FcExprCreateDouble (double d) FcExpr * FcExprCreateString (const FcChar8 *s) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpString; e->u.sval = FcStrCopy (s); } @@ -114,11 +119,9 @@ FcExprCreateString (const FcChar8 *s) FcExpr * FcExprCreateMatrix (const FcMatrix *m) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpMatrix; e->u.mval = FcMatrixCopy (m); } @@ -128,11 +131,9 @@ FcExprCreateMatrix (const FcMatrix *m) FcExpr * FcExprCreateBool (FcBool b) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpBool; e->u.bval = b; } @@ -142,8 +143,7 @@ FcExprCreateBool (FcBool b) FcExpr * FcExprCreateNil (void) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); @@ -155,11 +155,9 @@ FcExprCreateNil (void) FcExpr * FcExprCreateField (const char *field) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpField; e->u.object = FcObjectFromName (field); } @@ -169,11 +167,9 @@ FcExprCreateField (const char *field) FcExpr * FcExprCreateConst (const FcChar8 *constant) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpConst; e->u.constant = FcStrCopy (constant); } @@ -183,11 +179,9 @@ FcExprCreateConst (const FcChar8 *constant) FcExpr * FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right) { - FcExpr *e = (FcExpr *) malloc (sizeof (FcExpr)); - + FcExpr *e = FcExprAlloc (); if (e) { - FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = op; e->u.tree.left = left; e->u.tree.right = right; @@ -272,12 +266,6 @@ FcEditDestroy (FcEdit *e) free (e); } -char * -FcConfigSaveField (const char *field) -{ - return (char *) FcStrCopy ((FcChar8 *) field); -} - typedef enum _FcElement { FcElementNone, FcElementFontconfig, @@ -414,6 +402,7 @@ typedef struct _FcPStack { FcElement element; FcChar8 **attr; FcStrBuf str; + FcChar8 *attr_buf_static[16]; } FcPStack; typedef enum _FcVStackTag { @@ -469,6 +458,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 +690,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 +826,73 @@ 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 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; + } + + 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 +909,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 +923,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 +950,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 +984,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 +1004,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 +1230,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 +1252,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,17 +1322,17 @@ 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); @@ -1386,7 +1389,7 @@ FcParseAlias (FcConfigParse *parse) if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding)) return; - while ((vstack = FcVStackPop (parse))) + while ((vstack = FcVStackPeek (parse))) { switch (vstack->tag) { case FcVStackFamily: @@ -1428,7 +1431,7 @@ FcParseAlias (FcConfigParse *parse) FcConfigMessage (parse, FcSevereWarning, "bad alias"); break; } - FcVStackDestroy (vstack); + FcVStackPopAndDestroy (parse); } if (!family) { @@ -1497,7 +1500,7 @@ FcParseAlias (FcConfigParse *parse) static FcExpr * FcPopExpr (FcConfigParse *parse) { - FcVStack *vstack = FcVStackPop (parse); + FcVStack *vstack = FcVStackPeek (parse); FcExpr *expr = 0; if (!vstack) return 0; @@ -1546,7 +1549,7 @@ FcPopExpr (FcConfigParse *parse) default: break; } - FcVStackDestroy (vstack); + FcVStackPopAndDestroy (parse); return expr; } @@ -1849,7 +1852,7 @@ FcParseMatch (FcConfigParse *parse) return; } } - while ((vstack = FcVStackPop (parse))) + while ((vstack = FcVStackPeek (parse))) { switch (vstack->tag) { case FcVStackTest: @@ -1872,7 +1875,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 +1886,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element) { FcVStack *vstack; - while ((vstack = FcVStackPop (parse))) + while ((vstack = FcVStackPeek (parse))) { switch (vstack->tag) { case FcVStackGlob: @@ -1908,7 +1911,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element) FcConfigMessage (parse, FcSevereWarning, "bad font selector"); break; } - FcVStackDestroy (vstack); + FcVStackPopAndDestroy (parse); } } @@ -1916,7 +1919,7 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element) static FcValue FcPopValue (FcConfigParse *parse) { - FcVStack *vstack = FcVStackPop (parse); + FcVStack *vstack = FcVStackPeek (parse); FcValue value; value.type = FcTypeVoid; @@ -1956,7 +1959,7 @@ FcPopValue (FcConfigParse *parse) vstack->tag); break; } - FcVStackDestroy (vstack); + FcVStackPopAndDestroy (parse); return value; } @@ -2011,7 +2014,7 @@ FcParsePattern (FcConfigParse *parse) return; } - while ((vstack = FcVStackPop (parse))) + while ((vstack = FcVStackPeek (parse))) { switch (vstack->tag) { case FcVStackPattern: @@ -2026,7 +2029,7 @@ FcParsePattern (FcConfigParse *parse) FcConfigMessage (parse, FcSevereWarning, "unknown pattern element"); break; } - FcVStackDestroy (vstack); + FcVStackPopAndDestroy (parse); } FcVStackPushPattern (parse, pattern);