X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcxml.c;h=f60e24835936c25b1871d39daedc0819f8e952bf;hb=3ed70071cdc8a03229c009f5565c23948264a5e0;hp=4087183372a5f4665ba15a910b03e37e36030a20;hpb=766a9b2f61458202be0fbf5745ce1e02ecd95c6e;p=fontconfig.git diff --git a/src/fcxml.c b/src/fcxml.c index 4087183..f60e248 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -1,5 +1,5 @@ /* - * $RCSId: xc/lib/fontconfig/src/fcxml.c,v 1.21 2002/08/22 18:53:22 keithp Exp $ + * fontconfig/src/fcxml.c * * Copyright © 2002 Keith Packard * @@ -450,7 +450,7 @@ typedef struct _FcVStack { int integer; double _double; FcMatrix *matrix; - FcBool bool; + FcBool bool_; FcTest *test; FcQual qual; @@ -558,6 +558,10 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) const FcObjectType *o; const FcConstant *c; + /* If parsing the expression failed, some nodes may be NULL */ + if (!expr) + return; + switch (expr->op) { case FcOpInteger: case FcOpDouble: @@ -817,12 +821,12 @@ FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix) } static FcBool -FcVStackPushBool (FcConfigParse *parse, FcBool bool) +FcVStackPushBool (FcConfigParse *parse, FcBool bool_) { FcVStack *vstack = FcVStackCreate (); if (!vstack) return FcFalse; - vstack->u.bool = bool; + vstack->u.bool_ = bool_; vstack->tag = FcVStackBool; FcVStackPush (parse, vstack); return FcTrue; @@ -964,7 +968,12 @@ FcPStackPush (FcConfigParse *parse, FcElement element, const XML_Char **attr) { new->attr = FcConfigSaveAttr (attr); if (!new->attr) + { FcConfigMessage (parse, FcSevereError, "out of memory"); + FcMemFree (FC_MEM_PSTACK, sizeof (FcPStack)); + free (new); + return FcFalse; + } } else new->attr = 0; @@ -1105,7 +1114,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"); @@ -1117,7 +1126,7 @@ FcParseInt (FcConfigParse *parse) FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid integer", s); else FcVStackPushInteger (parse, l); - FcStrFree (s); + FcStrBufDestroy (&parse->pstack->str); } /* @@ -1186,7 +1195,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"); @@ -1198,7 +1207,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 @@ -1257,13 +1266,13 @@ FcParseMatrix (FcConfigParse *parse) } static FcBool -FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool) +FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_) { FcBool result = FcFalse; - if (!FcNameBool (bool, &result)) + if (!FcNameBool (bool_, &result)) FcConfigMessage (parse, FcSevereWarning, "\"%s\" is not known boolean", - bool); + bool_); return result; } @@ -1274,14 +1283,41 @@ 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 +FcConfigLexBinding (FcConfigParse *parse, + const FcChar8 *binding_string, + FcValueBinding *binding_ret) +{ + FcValueBinding binding; + + if (!binding_string) + binding = FcValueBindingWeak; + else + { + if (!strcmp ((char *) binding_string, "weak")) + 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 binding \"%s\"", binding_string); + return FcFalse; + } + } + *binding_ret = binding; + return FcTrue; } static void @@ -1334,14 +1370,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); } @@ -1353,7 +1389,10 @@ FcParseAlias (FcConfigParse *parse) FcEdit *edit = 0, *next; FcVStack *vstack; FcTest *test; + FcValueBinding binding; + if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding)) + return; while ((vstack = FcVStackPop (parse))) { switch (vstack->tag) { @@ -1415,7 +1454,7 @@ FcParseAlias (FcConfigParse *parse) FC_FAMILY_OBJECT, FcOpPrepend, prefer, - FcValueBindingWeak); + binding); if (edit) edit->next = 0; else @@ -1428,7 +1467,7 @@ FcParseAlias (FcConfigParse *parse) FC_FAMILY_OBJECT, FcOpAppend, accept, - FcValueBindingWeak); + binding); if (edit) edit->next = next; else @@ -1441,7 +1480,7 @@ FcParseAlias (FcConfigParse *parse) FC_FAMILY_OBJECT, FcOpAppendLast, def, - FcValueBindingWeak); + binding); if (edit) edit->next = next; else @@ -1501,7 +1540,7 @@ FcPopExpr (FcConfigParse *parse) expr = FcExprCreateMatrix (vstack->u.matrix); break; case FcVStackBool: - expr = FcExprCreateBool (vstack->u.bool); + expr = FcExprCreateBool (vstack->u.bool_); break; case FcVStackTest: break; @@ -1597,7 +1636,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"); @@ -1608,7 +1647,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 { @@ -1646,7 +1685,6 @@ FcConfigLexCompare (const FcChar8 *compare) return FcConfigLexOp (compare, fcCompareOps, NUM_COMPARE_OPS); } - static void FcParseTest (FcConfigParse *parse) { @@ -1753,7 +1791,6 @@ FcParseEdit (FcConfigParse *parse) { const FcChar8 *name; const FcChar8 *mode_string; - const FcChar8 *binding_string; FcOp mode; FcValueBinding binding; FcExpr *expr; @@ -1777,23 +1814,9 @@ FcParseEdit (FcConfigParse *parse) return; } } - binding_string = FcConfigGetAttribute (parse, "binding"); - if (!binding_string) - binding = FcValueBindingWeak; - else - { - if (!strcmp ((char *) binding_string, "weak")) - 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; - } - } + if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding)) + return; + expr = FcPopBinary (parse, FcOpComma); edit = FcEditCreate (parse, FcObjectFromName ((char *) name), mode, expr, binding); @@ -1845,6 +1868,12 @@ FcParseMatch (FcConfigParse *parse) vstack->u.edit->next = edit; edit = vstack->u.edit; vstack->tag = FcVStackNone; + if (kind == FcMatchScan && edit->object > FC_MAX_BASE_OBJECT) + { + FcConfigMessage (parse, FcSevereError, + " cannot edit user-defined object \"%s\"", + FcObjectName(edit->object)); + } break; default: FcConfigMessage (parse, FcSevereWarning, "invalid match element"); @@ -1926,7 +1955,7 @@ FcPopValue (FcConfigParse *parse) value.type = FcTypeMatrix; break; case FcVStackBool: - value.u.b = vstack->u.bool; + value.u.b = vstack->u.bool_; value.type = FcTypeBool; break; default: @@ -1968,8 +1997,10 @@ FcParsePatelt (FcConfigParse *parse) if (!FcPatternAdd (pattern, name, value, FcTrue)) { FcConfigMessage (parse, FcSevereError, "out of memory"); + FcValueDestroy(value); break; } + FcValueDestroy(value); } FcVStackPushPattern (parse, pattern); @@ -2022,14 +2053,56 @@ 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"); break; } #ifdef _WIN32 - if (strcmp (data, "WINDOWSFONTDIR") == 0) + 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)) + { + FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed"); + FcStrFree (data); + break; + } + p = strrchr (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)) + { + FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed"); + FcStrFree (data); + break; + } + p = strrchr (data, '\\'); + if (p) *p = '\0'; + strcat (data, "\\..\\share\\fonts"); + } + else if (strcmp (data, "WINDOWSFONTDIR") == 0) { int rc; FcStrFree (data); @@ -2052,12 +2125,14 @@ FcEndElement(void *userData, const XML_Char *name) strcat (data, "fonts"); } #endif - if (!FcStrUsesHome (data) || FcConfigHome ()) + if (strlen ((char *) data) == 0) + FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored"); + else if (!FcStrUsesHome (data) || FcConfigHome ()) { 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); @@ -2066,6 +2141,30 @@ FcEndElement(void *userData, const XML_Char *name) FcConfigMessage (parse, FcSevereError, "out of memory"); break; } +#ifdef _WIN32 + if (strcmp (data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0) + { + int rc; + FcStrFree (data); + data = malloc (1000); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + break; + } + FcMemAlloc (FC_MEM_STRING, 1000); + rc = GetTempPath (800, data); + if (rc == 0 || rc > 800) + { + FcConfigMessage (parse, FcSevereError, "GetWindowsDirectory failed"); + FcStrFree (data); + break; + } + if (data [strlen (data) - 1] != '\\') + strcat (data, "\\"); + strcat (data, "fontconfig\\cache"); + } +#endif if (!FcStrUsesHome (data) || FcConfigHome ()) { if (!FcConfigAddCacheDir (parse->config, data)) @@ -2075,14 +2174,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); @@ -2281,6 +2380,14 @@ FcEndDoctypeDecl (void *userData) #endif /* ENABLE_LIBXML2 */ +static int +FcSortCmpStr (const void *a, const void *b) +{ + const FcChar8 *as = *((FcChar8 **) a); + const FcChar8 *bs = *((FcChar8 **) b); + return FcStrCmp (as, bs); +} + static FcBool FcConfigParseAndLoadDir (FcConfig *config, const FcChar8 *name, @@ -2350,7 +2457,7 @@ FcConfigParseAndLoadDir (FcConfig *config, { int i; qsort (files->strs, files->num, sizeof (FcChar8 *), - (int (*)(const void *, const void *)) FcStrCmp); + (int (*)(const void *, const void *)) FcSortCmpStr); for (i = 0; ret && i < files->num; i++) ret = FcConfigParseAndLoad (config, files->strs[i], complain); }