X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcxml.c;h=e8cfe1fbdbaa078d2c74a139196f5fdd86639c2d;hb=681bb379de1847cf288ba27cf29243c8395cff17;hp=e718ca2ea5f6cdc450556b8cf5fffe6703a6d94a;hpb=cb6d97eb1baba6795bb8abdede69902b2440f371;p=fontconfig.git diff --git a/src/fcxml.c b/src/fcxml.c index e718ca2..e8cfe1f 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -22,11 +22,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include #include "fcint.h" +#include +#include #include -#if ENABLE_LIBXML2 +#ifdef ENABLE_LIBXML2 #include @@ -64,7 +65,6 @@ FcTestDestroy (FcTest *test) if (test->next) FcTestDestroy (test->next); FcExprDestroy (test->expr); - FcStrFree ((FcChar8 *) test->field); FcMemFree (FC_MEM_TEST, sizeof (FcTest)); free (test); } @@ -161,7 +161,7 @@ FcExprCreateField (const char *field) { FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr)); e->op = FcOpField; - e->u.field = (char *) FcStrCopy ((FcChar8 *) field); + e->u.object = FcObjectFromName (field); } return e; } @@ -217,7 +217,6 @@ FcExprDestroy (FcExpr *e) case FcOpBool: break; case FcOpField: - FcStrFree ((FcChar8 *) e->u.field); break; case FcOpConst: FcStrFree (e->u.constant); @@ -268,7 +267,6 @@ FcEditDestroy (FcEdit *e) { if (e->next) FcEditDestroy (e->next); - FcStrFree ((FcChar8 *) e->field); if (e->expr) FcExprDestroy (e->expr); free (e); @@ -284,6 +282,7 @@ typedef enum _FcElement { FcElementNone, FcElementFontconfig, FcElementDir, + FcElementCacheDir, FcElementCache, FcElementInclude, FcElementConfig, @@ -338,12 +337,13 @@ typedef enum _FcElement { FcElementUnknown } FcElement; -static struct { +static const struct { const char name[16]; FcElement element; } fcElementMap[] = { { "fontconfig", FcElementFontconfig }, { "dir", FcElementDir }, + { "cachedir", FcElementCacheDir }, { "cache", FcElementCache }, { "include", FcElementInclude }, { "config", FcElementConfig }, @@ -492,10 +492,10 @@ FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, const char *fmt, { if (parse->name) fprintf (stderr, "Fontconfig %s: \"%s\", line %d: ", s, - parse->name, XML_GetCurrentLineNumber (parse->parser)); + parse->name, (int)XML_GetCurrentLineNumber (parse->parser)); else fprintf (stderr, "Fontconfig %s: line %d: ", s, - XML_GetCurrentLineNumber (parse->parser)); + (int)XML_GetCurrentLineNumber (parse->parser)); if (severe >= FcSevereError) parse->error = FcTrue; } @@ -545,6 +545,8 @@ FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type) if ((value == FcTypeLangSet && type == FcTypeString) || (value == FcTypeString && type == FcTypeLangSet)) return; + if (type == (FcType) -1) + return; FcConfigMessage (parse, FcSevereWarning, "saw %s, expected %s", FcTypeName (value), FcTypeName (type)); } @@ -556,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: @@ -576,7 +582,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) case FcOpNil: break; case FcOpField: - o = FcNameGetObjectType (expr->u.field); + o = FcNameGetObjectType (FcObjectName (expr->u.object)); if (o) FcTypecheckValue (parse, o->type, type); break; @@ -656,10 +662,10 @@ FcTestCreate (FcConfigParse *parse, test->next = 0; test->kind = kind; test->qual = qual; - test->field = (char *) FcStrCopy (field); + test->object = FcObjectFromName ((const char *) field); test->op = compare; test->expr = expr; - o = FcNameGetObjectType (test->field); + o = FcNameGetObjectType (FcObjectName (test->object)); if (o) FcTypecheckExpr (parse, expr, o->type); } @@ -668,7 +674,7 @@ FcTestCreate (FcConfigParse *parse, static FcEdit * FcEditCreate (FcConfigParse *parse, - const char *field, + FcObject object, FcOp op, FcExpr *expr, FcValueBinding binding) @@ -680,11 +686,11 @@ FcEditCreate (FcConfigParse *parse, const FcObjectType *o; e->next = 0; - e->field = field; /* already saved in grammar */ + e->object = object; e->op = op; e->expr = expr; e->binding = binding; - o = FcNameGetObjectType (e->field); + o = FcNameGetObjectType (FcObjectName (e->object)); if (o) FcTypecheckExpr (parse, expr, o->type); } @@ -923,7 +929,6 @@ FcVStackElements (FcConfigParse *parse) static FcChar8 ** FcConfigSaveAttr (const XML_Char **attr) { - int n; int slen; int i; FcChar8 **new; @@ -934,7 +939,6 @@ FcConfigSaveAttr (const XML_Char **attr) slen = 0; for (i = 0; attr[i]; i++) slen += strlen ((char *) attr[i]) + 1; - n = i; new = malloc ((i + 1) * sizeof (FcChar8 *) + slen); if (!new) return 0; @@ -1024,6 +1028,9 @@ FcConfigGetAttribute (FcConfigParse *parse, const char *attr) return 0; attrs = parse->pstack->attr; + if (!attrs) + return 0; + while (*attrs) { if (!strcmp ((char *) *attrs, attr)) @@ -1281,6 +1288,33 @@ FcParseBool (FcConfigParse *parse) FcStrFree (s); } +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 FcParseFamilies (FcConfigParse *parse, FcVStackTag tag) { @@ -1318,8 +1352,7 @@ FcParseFamilies (FcConfigParse *parse, FcVStackTag tag) if (!FcVStackPushExpr (parse, tag, expr)) { FcConfigMessage (parse, FcSevereError, "out of memory"); - if (expr) - FcExprDestroy (expr); + FcExprDestroy (expr); } } } @@ -1351,7 +1384,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) { @@ -1410,10 +1446,10 @@ FcParseAlias (FcConfigParse *parse) if (prefer) { edit = FcEditCreate (parse, - FcConfigSaveField ("family"), + FC_FAMILY_OBJECT, FcOpPrepend, prefer, - FcValueBindingWeak); + binding); if (edit) edit->next = 0; else @@ -1423,10 +1459,10 @@ FcParseAlias (FcConfigParse *parse) { next = edit; edit = FcEditCreate (parse, - FcConfigSaveField ("family"), + FC_FAMILY_OBJECT, FcOpAppend, accept, - FcValueBindingWeak); + binding); if (edit) edit->next = next; else @@ -1436,10 +1472,10 @@ FcParseAlias (FcConfigParse *parse) { next = edit; edit = FcEditCreate (parse, - FcConfigSaveField ("family"), + FC_FAMILY_OBJECT, FcOpAppendLast, def, - FcValueBindingWeak); + binding); if (edit) edit->next = next; else @@ -1540,7 +1576,7 @@ FcPopBinary (FcConfigParse *parse, FcOp op) FcConfigMessage (parse, FcSevereError, "out of memory"); FcExprDestroy (left); FcExprDestroy (expr); - break; + return 0; } expr = new; } @@ -1644,7 +1680,6 @@ FcConfigLexCompare (const FcChar8 *compare) return FcConfigLexOp (compare, fcCompareOps, NUM_COMPARE_OPS); } - static void FcParseTest (FcConfigParse *parse) { @@ -1667,6 +1702,8 @@ FcParseTest (FcConfigParse *parse) kind = FcMatchPattern; else if (!strcmp ((char *) kind_string, "font")) kind = FcMatchFont; + else if (!strcmp ((char *) kind_string, "scan")) + kind = FcMatchScan; else if (!strcmp ((char *) kind_string, "default")) kind = FcMatchDefault; else @@ -1749,7 +1786,6 @@ FcParseEdit (FcConfigParse *parse) { const FcChar8 *name; const FcChar8 *mode_string; - const FcChar8 *binding_string; FcOp mode; FcValueBinding binding; FcExpr *expr; @@ -1773,25 +1809,12 @@ 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, (char *) FcStrCopy (name), mode, expr, binding); + edit = FcEditCreate (parse, FcObjectFromName ((char *) name), + mode, expr, binding); if (!edit) { FcConfigMessage (parse, FcSevereError, "out of memory"); @@ -1820,6 +1843,8 @@ FcParseMatch (FcConfigParse *parse) kind = FcMatchPattern; else if (!strcmp ((char *) kind_name, "font")) kind = FcMatchFont; + else if (!strcmp ((char *) kind_name, "scan")) + kind = FcMatchScan; else { FcConfigMessage (parse, FcSevereWarning, "invalid match target \"%s\"", kind_name); @@ -1838,6 +1863,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"); @@ -1949,6 +1980,7 @@ FcParsePatelt (FcConfigParse *parse) if (!name) { FcConfigMessage (parse, FcSevereWarning, "missing pattern element name"); + FcPatternDestroy (pattern); return; } @@ -1986,6 +2018,7 @@ FcParsePattern (FcConfigParse *parse) if (!FcPatternAppend (pattern, vstack->u.pattern)) { FcConfigMessage (parse, FcSevereError, "out of memory"); + FcPatternDestroy (pattern); return; } break; @@ -2046,11 +2079,11 @@ FcEndElement(void *userData, const XML_Char *name) if (!FcStrUsesHome (data) || FcConfigHome ()) { if (!FcConfigAddDir (parse->config, data)) - FcConfigMessage (parse, FcSevereError, "out of memory"); + FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data); } FcStrFree (data); break; - case FcElementCache: + case FcElementCacheDir: data = FcStrBufDone (&parse->pstack->str); if (!data) { @@ -2059,11 +2092,22 @@ FcEndElement(void *userData, const XML_Char *name) } if (!FcStrUsesHome (data) || FcConfigHome ()) { - if (!FcConfigSetCache (parse->config, data)) - FcConfigMessage (parse, FcSevereError, "out of memory"); + if (!FcConfigAddCacheDir (parse->config, data)) + FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data); } FcStrFree (data); break; + + case FcElementCache: + data = FcStrBufDone (&parse->pstack->str); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + break; + } + /* discard this data; no longer used */ + FcStrFree (data); + break; case FcElementInclude: FcParseInclude (parse); break; @@ -2232,7 +2276,7 @@ FcStartDoctypeDecl (void *userData, FcConfigMessage (parse, FcSevereError, "invalid doctype \"%s\"", doctypeName); } -#if ENABLE_LIBXML2 +#ifdef ENABLE_LIBXML2 static void FcInternalSubsetDecl (void *userData, @@ -2261,6 +2305,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, @@ -2330,7 +2382,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); } @@ -2352,12 +2404,12 @@ FcConfigParseAndLoad (FcConfig *config, XML_Parser p; FcChar8 *filename; - FILE *f; + int fd; int len; FcConfigParse parse; FcBool error = FcTrue; -#if ENABLE_LIBXML2 +#ifdef ENABLE_LIBXML2 xmlSAXHandler sax; char buf[BUFSIZ]; #else @@ -2390,13 +2442,13 @@ FcConfigParseAndLoad (FcConfig *config, if (FcDebug () & FC_DBG_CONFIG) printf ("\tLoading config file %s\n", filename); - f = fopen ((char *) filename, "r"); - if (!f) { + fd = open ((char *) filename, O_RDONLY); + if (fd == -1) { FcStrFree (filename); goto bail0; } -#if ENABLE_LIBXML2 +#ifdef ENABLE_LIBXML2 memset(&sax, 0, sizeof(sax)); sax.internalSubset = FcInternalSubsetDecl; @@ -2417,7 +2469,7 @@ FcConfigParseAndLoad (FcConfig *config, if (!FcConfigInit (&parse, name, config, p)) goto bail2; -#if !ENABLE_LIBXML2 +#ifndef ENABLE_LIBXML2 XML_SetUserData (p, &parse); @@ -2428,7 +2480,7 @@ FcConfigParseAndLoad (FcConfig *config, #endif /* ENABLE_LIBXML2 */ do { -#if !ENABLE_LIBXML2 +#ifndef ENABLE_LIBXML2 buf = XML_GetBuffer (p, BUFSIZ); if (!buf) { @@ -2436,14 +2488,14 @@ FcConfigParseAndLoad (FcConfig *config, goto bail3; } #endif - len = fread (buf, 1, BUFSIZ, f); + len = read (fd, buf, BUFSIZ); if (len < 0) { FcConfigMessage (&parse, FcSevereError, "failed reading config file"); goto bail3; } -#if ENABLE_LIBXML2 +#ifdef ENABLE_LIBXML2 if (xmlParseChunk (p, buf, len, len == 0)) #else if (!XML_ParseBuffer (p, len, len == 0)) @@ -2460,8 +2512,8 @@ bail3: bail2: XML_ParserFree (p); bail1: - fclose (f); - f = NULL; + close (fd); + fd = -1; bail0: if (error && complain) { @@ -2473,3 +2525,6 @@ bail0: } return FcTrue; } +#define __fcxml__ +#include "fcaliastail.h" +#undef __fcxml__