/*
 * fontconfig/src/fcxml.c
 *
 * Copyright © 2002 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * 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
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include <string.h>
#include "fcint.h"
#include <fcntl.h>
#include <stdarg.h>
#include <dirent.h>

#ifdef ENABLE_LIBXML2

#include <libxml/parser.h>

#define XML_Char			xmlChar
#define XML_Parser			xmlParserCtxtPtr
#define XML_ParserFree			xmlFreeParserCtxt
#define XML_GetCurrentLineNumber	xmlSAX2GetLineNumber
#define XML_GetErrorCode		xmlCtxtGetLastError
#define XML_ErrorString(Error)		(Error)->message

#else /* ENABLE_LIBXML2 */

#ifndef HAVE_XMLPARSE_H
#define HAVE_XMLPARSE_H 0
#endif

#if HAVE_XMLPARSE_H
#include <xmlparse.h>
#else
#include <expat.h>
#endif

#endif /* ENABLE_LIBXML2 */

#ifdef _WIN32
#include <mbstring.h>
extern FcChar8 fontconfig_instprefix[];
#endif

static FcChar8  *__fc_userdir = NULL;
static FcChar8  *__fc_userconf = NULL;

static void
FcExprDestroy (FcExpr *e);
static FcBool
_FcConfigParse (FcConfig	*config,
		const FcChar8	*name,
		FcBool		complain,
		FcBool		load);

void
FcTestDestroy (FcTest *test)
{
    FcExprDestroy (test->expr);
    free (test);
}

void
FcRuleDestroy (FcRule *rule)
{
    FcRule *n = rule->next;

    switch (rule->type) {
    case FcRuleTest:
	FcTestDestroy (rule->u.test);
	break;
    case FcRuleEdit:
	FcEditDestroy (rule->u.edit);
	break;
    case FcRuleUnknown:
    default:
	break;
    }
    free (rule);
    if (n)
	FcRuleDestroy (n);
}

static FcExpr *
FcExprCreateInteger (FcConfig *config, int i)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpInteger;
	e->u.ival = i;
    }
    return e;
}

static FcExpr *
FcExprCreateDouble (FcConfig *config, double d)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpDouble;
	e->u.dval = d;
    }
    return e;
}

static FcExpr *
FcExprCreateString (FcConfig *config, const FcChar8 *s)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpString;
	e->u.sval = FcStrdup (s);
    }
    return e;
}

static FcExprMatrix *
FcExprMatrixCopyShallow (const FcExprMatrix *matrix)
{
  FcExprMatrix *m = malloc (sizeof (FcExprMatrix));
  if (m)
  {
    *m = *matrix;
  }
  return m;
}

static void
FcExprMatrixFreeShallow (FcExprMatrix *m)
{
  if (!m)
    return;

  free (m);
}

static void
FcExprMatrixFree (FcExprMatrix *m)
{
  if (!m)
    return;

  FcExprDestroy (m->xx);
  FcExprDestroy (m->xy);
  FcExprDestroy (m->yx);
  FcExprDestroy (m->yy);

  free (m);
}

static FcExpr *
FcExprCreateMatrix (FcConfig *config, const FcExprMatrix *matrix)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpMatrix;
	e->u.mexpr = FcExprMatrixCopyShallow (matrix);
    }
    return e;
}

static FcExpr *
FcExprCreateRange (FcConfig *config, FcRange *range)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpRange;
	e->u.rval = FcRangeCopy (range);
    }
    return e;
}

static FcExpr *
FcExprCreateBool (FcConfig *config, FcBool b)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpBool;
	e->u.bval = b;
    }
    return e;
}

static FcExpr *
FcExprCreateCharSet (FcConfig *config, FcCharSet *charset)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpCharSet;
	e->u.cval = FcCharSetCopy (charset);
    }
    return e;
}

static FcExpr *
FcExprCreateLangSet (FcConfig *config, FcLangSet *langset)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpLangSet;
	e->u.lval = FcLangSetCopy (langset);
    }
    return e;
}

static FcExpr *
FcExprCreateName (FcConfig *config, FcExprName name)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpField;
	e->u.name = name;
    }
    return e;
}

static FcExpr *
FcExprCreateConst (FcConfig *config, const FcChar8 *constant)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = FcOpConst;
	e->u.constant = FcStrdup (constant);
    }
    return e;
}

static FcExpr *
FcExprCreateOp (FcConfig *config, FcExpr *left, FcOp op, FcExpr *right)
{
    FcExpr *e = FcConfigAllocExpr (config);
    if (e)
    {
	e->op = op;
	e->u.tree.left = left;
	e->u.tree.right = right;
    }
    return e;
}

static void
FcExprDestroy (FcExpr *e)
{
    if (!e)
	return;
    switch (FC_OP_GET_OP (e->op)) {
    case FcOpInteger:
	break;
    case FcOpDouble:
	break;
    case FcOpString:
	FcFree (e->u.sval);
	break;
    case FcOpMatrix:
	FcExprMatrixFree (e->u.mexpr);
	break;
    case FcOpRange:
	FcRangeDestroy (e->u.rval);
	break;
    case FcOpCharSet:
	FcCharSetDestroy (e->u.cval);
	break;
    case FcOpLangSet:
	FcLangSetDestroy (e->u.lval);
	break;
    case FcOpBool:
	break;
    case FcOpField:
	break;
    case FcOpConst:
	FcFree (e->u.constant);
	break;
    case FcOpAssign:
    case FcOpAssignReplace:
    case FcOpPrepend:
    case FcOpPrependFirst:
    case FcOpAppend:
    case FcOpAppendLast:
    case FcOpDelete:
    case FcOpDeleteAll:
	break;
    case FcOpOr:
    case FcOpAnd:
    case FcOpEqual:
    case FcOpNotEqual:
    case FcOpLess:
    case FcOpLessEqual:
    case FcOpMore:
    case FcOpMoreEqual:
    case FcOpContains:
    case FcOpListing:
    case FcOpNotContains:
    case FcOpPlus:
    case FcOpMinus:
    case FcOpTimes:
    case FcOpDivide:
    case FcOpQuest:
    case FcOpComma:
	FcExprDestroy (e->u.tree.right);
	/* fall through */
    case FcOpNot:
    case FcOpFloor:
    case FcOpCeil:
    case FcOpRound:
    case FcOpTrunc:
	FcExprDestroy (e->u.tree.left);
	break;
    case FcOpNil:
    case FcOpInvalid:
	break;
    }

    e->op = FcOpNil;
}

void
FcEditDestroy (FcEdit *e)
{
    if (e->expr)
	FcExprDestroy (e->expr);
    free (e);
}

typedef enum _FcElement {
    FcElementNone,
    FcElementFontconfig,
    FcElementDir,
    FcElementCacheDir,
    FcElementCache,
    FcElementInclude,
    FcElementConfig,
    FcElementMatch,
    FcElementAlias,
    FcElementDescription,
    FcElementRemapDir,
    FcElementResetDirs,
	
    FcElementRescan,

    FcElementPrefer,
    FcElementAccept,
    FcElementDefault,
    FcElementFamily,

    FcElementSelectfont,
    FcElementAcceptfont,
    FcElementRejectfont,
    FcElementGlob,
    FcElementPattern,
    FcElementPatelt,

    FcElementTest,
    FcElementEdit,
    FcElementInt,
    FcElementDouble,
    FcElementString,
    FcElementMatrix,
    FcElementRange,
    FcElementBool,
    FcElementCharSet,
    FcElementLangSet,
    FcElementName,
    FcElementConst,
    FcElementOr,
    FcElementAnd,
    FcElementEq,
    FcElementNotEq,
    FcElementLess,
    FcElementLessEq,
    FcElementMore,
    FcElementMoreEq,
    FcElementContains,
    FcElementNotContains,
    FcElementPlus,
    FcElementMinus,
    FcElementTimes,
    FcElementDivide,
    FcElementNot,
    FcElementIf,
    FcElementFloor,
    FcElementCeil,
    FcElementRound,
    FcElementTrunc,
    FcElementUnknown
} FcElement;

static const struct {
    const char  name[16];
    FcElement   element;
} fcElementMap[] = {
    { "fontconfig",	FcElementFontconfig },
    { "dir",		FcElementDir },
    { "cachedir",	FcElementCacheDir },
    { "cache",		FcElementCache },
    { "include",	FcElementInclude },
    { "config",		FcElementConfig },
    { "match",		FcElementMatch },
    { "alias",		FcElementAlias },
    { "description",	FcElementDescription },
    { "remap-dir",	FcElementRemapDir },
    { "reset-dirs",	FcElementResetDirs },

    { "rescan",		FcElementRescan },

    { "prefer",		FcElementPrefer },
    { "accept",		FcElementAccept },
    { "default",	FcElementDefault },
    { "family",		FcElementFamily },

    { "selectfont",	FcElementSelectfont },
    { "acceptfont",	FcElementAcceptfont },
    { "rejectfont",	FcElementRejectfont },
    { "glob",		FcElementGlob },
    { "pattern",	FcElementPattern },
    { "patelt",		FcElementPatelt },

    { "test",		FcElementTest },
    { "edit",		FcElementEdit },
    { "int",		FcElementInt },
    { "double",		FcElementDouble },
    { "string",		FcElementString },
    { "matrix",		FcElementMatrix },
    { "range",		FcElementRange },
    { "bool",		FcElementBool },
    { "charset",	FcElementCharSet },
    { "langset",	FcElementLangSet },
    { "name",		FcElementName },
    { "const",		FcElementConst },
    { "or",		FcElementOr },
    { "and",		FcElementAnd },
    { "eq",		FcElementEq },
    { "not_eq",		FcElementNotEq },
    { "less",		FcElementLess },
    { "less_eq",	FcElementLessEq },
    { "more",		FcElementMore },
    { "more_eq",	FcElementMoreEq },
    { "contains",	FcElementContains },
    { "not_contains",	FcElementNotContains },
    { "plus",		FcElementPlus },
    { "minus",		FcElementMinus },
    { "times",		FcElementTimes },
    { "divide",		FcElementDivide },
    { "not",		FcElementNot },
    { "if",		FcElementIf },
    { "floor",		FcElementFloor },
    { "ceil",		FcElementCeil },
    { "round",		FcElementRound },
    { "trunc",		FcElementTrunc },
};
#define NUM_ELEMENT_MAPS (int) (sizeof fcElementMap / sizeof fcElementMap[0])

static const char *fcElementIgnoreName[16] = {
    "its:",
    NULL
};

static FcElement
FcElementMap (const XML_Char *name)
{

    int	    i;
    for (i = 0; i < NUM_ELEMENT_MAPS; i++)
	if (!strcmp ((char *) name, fcElementMap[i].name))
	    return fcElementMap[i].element;
    for (i = 0; fcElementIgnoreName[i] != NULL; i++)
	if (!strncmp ((char *) name, fcElementIgnoreName[i], strlen (fcElementIgnoreName[i])))
	    return FcElementNone;
    return FcElementUnknown;
}

static const char *
FcElementReverseMap (FcElement e)
{
    int i;

    for (i = 0; i < NUM_ELEMENT_MAPS; i++)
	if (fcElementMap[i].element == e)
	    return fcElementMap[i].name;

    return NULL;
}


typedef struct _FcPStack {
    struct _FcPStack   *prev;
    FcElement		element;
    FcChar8		**attr;
    FcStrBuf		str;
    FcChar8            *attr_buf_static[16];
} FcPStack;

typedef enum _FcVStackTag {
    FcVStackNone,

    FcVStackString,
    FcVStackFamily,
    FcVStackConstant,
    FcVStackGlob,
    FcVStackName,
    FcVStackPattern,

    FcVStackPrefer,
    FcVStackAccept,
    FcVStackDefault,

    FcVStackInteger,
    FcVStackDouble,
    FcVStackMatrix,
    FcVStackRange,
    FcVStackBool,
    FcVStackCharSet,
    FcVStackLangSet,

    FcVStackTest,
    FcVStackExpr,
    FcVStackEdit
} FcVStackTag;

typedef struct _FcVStack {
    struct _FcVStack	*prev;
    FcPStack		*pstack;	/* related parse element */
    FcVStackTag		tag;
    union {
	FcChar8		*string;

	int		integer;
	double		_double;
	FcExprMatrix	*matrix;
	FcRange		*range;
	FcBool		bool_;
	FcCharSet	*charset;
	FcLangSet	*langset;
	FcExprName	name;

	FcTest		*test;
	FcQual		qual;
	FcOp		op;
	FcExpr		*expr;
	FcEdit		*edit;

	FcPattern	*pattern;
    } u;
} FcVStack;

typedef struct _FcConfigParse {
    FcPStack	    *pstack;
    FcVStack	    *vstack;
    FcBool	    error;
    const FcChar8   *name;
    FcConfig	    *config;
    FcRuleSet	    *ruleset;
    XML_Parser	    parser;
    unsigned int    pstack_static_used;
    FcPStack        pstack_static[8];
    unsigned int    vstack_static_used;
    FcVStack        vstack_static[64];
    FcBool          scanOnly;
} FcConfigParse;

typedef enum _FcConfigSeverity {
    FcSevereInfo, FcSevereWarning, FcSevereError
} FcConfigSeverity;

static void
FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, const char *fmt, ...)
{
    const char	*s = "unknown";
    va_list	args;

    va_start (args, fmt);

    switch (severe) {
    case FcSevereInfo: s = "info"; break;
    case FcSevereWarning: s = "warning"; break;
    case FcSevereError: s = "error"; break;
    }
    if (parse)
    {
	if (parse->name)
	    fprintf (stderr, "Fontconfig %s: \"%s\", line %d: ", s,
		     parse->name, (int)XML_GetCurrentLineNumber (parse->parser));
	else
	    fprintf (stderr, "Fontconfig %s: line %d: ", s,
		     (int)XML_GetCurrentLineNumber (parse->parser));
	if (severe >= FcSevereError)
	    parse->error = FcTrue;
    }
    else
	fprintf (stderr, "Fontconfig %s: ", s);
    vfprintf (stderr, fmt, args);
    fprintf (stderr, "\n");
    va_end (args);
}


static FcExpr *
FcPopExpr (FcConfigParse *parse);


static const char *
FcTypeName (FcType type)
{
    switch (type) {
    case FcTypeVoid:
	return "void";
    case FcTypeInteger:
    case FcTypeDouble:
	return "number";
    case FcTypeString:
	return "string";
    case FcTypeBool:
	return "bool";
    case FcTypeMatrix:
	return "matrix";
    case FcTypeCharSet:
	return "charset";
    case FcTypeFTFace:
	return "FT_Face";
    case FcTypeLangSet:
	return "langset";
    case FcTypeRange:
	return "range";
    case FcTypeUnknown:
    default:
	return "unknown";
    }
}

static void
FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type)
{
    if (value == FcTypeInteger)
	value = FcTypeDouble;
    if (type == FcTypeInteger)
	type = FcTypeDouble;
    if (value != type)
    {
	if ((value == FcTypeLangSet && type == FcTypeString) ||
	    (value == FcTypeString && type == FcTypeLangSet) ||
	    (value == FcTypeDouble && type == FcTypeRange))
	    return;
	if (type ==  FcTypeUnknown)
	    return;
	/* It's perfectly fine to use user-define elements in expressions,
	 * so don't warn in that case. */
	if (value == FcTypeUnknown)
	    return;
	FcConfigMessage (parse, FcSevereWarning, "saw %s, expected %s",
			 FcTypeName (value), FcTypeName (type));
    }
}

static void
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 (FC_OP_GET_OP (expr->op)) {
    case FcOpInteger:
    case FcOpDouble:
	FcTypecheckValue (parse, FcTypeDouble, type);
	break;
    case FcOpString:
	FcTypecheckValue (parse, FcTypeString, type);
	break;
    case FcOpMatrix:
	FcTypecheckValue (parse, FcTypeMatrix, type);
	break;
    case FcOpBool:
	FcTypecheckValue (parse, FcTypeBool, type);
	break;
    case FcOpCharSet:
	FcTypecheckValue (parse, FcTypeCharSet, type);
	break;
    case FcOpLangSet:
	FcTypecheckValue (parse, FcTypeLangSet, type);
	break;
    case FcOpRange:
	FcTypecheckValue (parse, FcTypeRange, type);
	break;
    case FcOpNil:
	break;
    case FcOpField:
	o = FcNameGetObjectType (FcObjectName (expr->u.name.object));
	if (o)
	    FcTypecheckValue (parse, o->type, type);
	break;
    case FcOpConst:
	c = FcNameGetConstant (expr->u.constant);
	if (c)
	{
	    o = FcNameGetObjectType (c->object);
	    if (o)
		FcTypecheckValue (parse, o->type, type);
	}
        else
            FcConfigMessage (parse, FcSevereWarning,
                             "invalid constant used : %s",
                             expr->u.constant);
	break;
    case FcOpQuest:
	FcTypecheckExpr (parse, expr->u.tree.left, FcTypeBool);
	FcTypecheckExpr (parse, expr->u.tree.right->u.tree.left, type);
	FcTypecheckExpr (parse, expr->u.tree.right->u.tree.right, type);
	break;
    case FcOpAssign:
    case FcOpAssignReplace:
	break;
    case FcOpEqual:
    case FcOpNotEqual:
    case FcOpLess:
    case FcOpLessEqual:
    case FcOpMore:
    case FcOpMoreEqual:
    case FcOpContains:
    case FcOpNotContains:
    case FcOpListing:
	FcTypecheckValue (parse, FcTypeBool, type);
	break;
    case FcOpComma:
    case FcOpOr:
    case FcOpAnd:
    case FcOpPlus:
    case FcOpMinus:
    case FcOpTimes:
    case FcOpDivide:
	FcTypecheckExpr (parse, expr->u.tree.left, type);
	FcTypecheckExpr (parse, expr->u.tree.right, type);
	break;
    case FcOpNot:
	FcTypecheckValue (parse, FcTypeBool, type);
	FcTypecheckExpr (parse, expr->u.tree.left, FcTypeBool);
	break;
    case FcOpFloor:
    case FcOpCeil:
    case FcOpRound:
    case FcOpTrunc:
	FcTypecheckValue (parse, FcTypeDouble, type);
	FcTypecheckExpr (parse, expr->u.tree.left, FcTypeDouble);
	break;
    default:
	break;
    }
}

static FcTest *
FcTestCreate (FcConfigParse *parse,
	      FcMatchKind   kind,
	      FcQual	    qual,
	      const FcChar8 *field,
	      unsigned int  compare,
	      FcExpr	    *expr)
{
    FcTest	*test = (FcTest *) malloc (sizeof (FcTest));

    if (test)
    {
	const FcObjectType	*o;
	
	test->kind = kind;
	test->qual = qual;
	test->object = FcObjectFromName ((const char *) field);
	test->op = compare;
	test->expr = expr;
	o = FcNameGetObjectType (FcObjectName (test->object));
	if (o)
	    FcTypecheckExpr (parse, expr, o->type);
    }
    return test;
}

static FcEdit *
FcEditCreate (FcConfigParse	*parse,
	      FcObject		object,
	      FcOp		op,
	      FcExpr		*expr,
	      FcValueBinding	binding)
{
    FcEdit *e = (FcEdit *) malloc (sizeof (FcEdit));

    if (e)
    {
	const FcObjectType	*o;

	e->object = object;
	e->op = op;
	e->expr = expr;
	e->binding = binding;
	o = FcNameGetObjectType (FcObjectName (e->object));
	if (o)
	    FcTypecheckExpr (parse, expr, o->type);
    }
    return e;
}

static FcRule *
FcRuleCreate (FcRuleType type,
	      void       *p)
{
    FcRule *r = (FcRule *) malloc (sizeof (FcRule));

    if (!r)
	return NULL;

    r->next = NULL;
    r->type = type;
    switch (type)
    {
    case FcRuleTest:
	r->u.test = (FcTest *) p;
	break;
    case FcRuleEdit:
	r->u.edit = (FcEdit *) p;
	break;
    case FcRuleUnknown:
    default:
	free (r);
	r = NULL;
	break;
    }

    return r;
}

static FcVStack *
FcVStackCreateAndPush (FcConfigParse *parse)
{
    FcVStack    *new;

    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;
    }
    new->tag = FcVStackNone;
    new->prev = 0;

    new->prev = parse->vstack;
    new->pstack = parse->pstack ? parse->pstack->prev : 0;
    parse->vstack = new;

    return new;
}

static FcBool
FcVStackPushString (FcConfigParse *parse, FcVStackTag tag, FcChar8 *string)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.string = string;
    vstack->tag = tag;
    return FcTrue;
}

static FcBool
FcVStackPushInteger (FcConfigParse *parse, int integer)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.integer = integer;
    vstack->tag = FcVStackInteger;
    return FcTrue;
}

static FcBool
FcVStackPushDouble (FcConfigParse *parse, double _double)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u._double = _double;
    vstack->tag = FcVStackDouble;
    return FcTrue;
}

static FcBool
FcVStackPushMatrix (FcConfigParse *parse, FcExprMatrix *matrix)
{
    FcVStack    *vstack;
    vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.matrix = FcExprMatrixCopyShallow (matrix);
    vstack->tag = FcVStackMatrix;
    return FcTrue;
}

static FcBool
FcVStackPushRange (FcConfigParse *parse, FcRange *range)
{
    FcVStack 	*vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.range = range;
    vstack->tag = FcVStackRange;
    return FcTrue;
}

static FcBool
FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.bool_ = bool_;
    vstack->tag = FcVStackBool;
    return FcTrue;
}

static FcBool
FcVStackPushCharSet (FcConfigParse *parse, FcCharSet *charset)
{
    FcVStack	*vstack;
    if (!charset)
	return FcFalse;
    vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.charset = charset;
    vstack->tag = FcVStackCharSet;
    return FcTrue;
}

static FcBool
FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset)
{
    FcVStack	*vstack;
    if (!langset)
	return FcFalse;
    vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.langset = langset;
    vstack->tag = FcVStackLangSet;
    return FcTrue;
}

static FcBool
FcVStackPushName (FcConfigParse *parse, FcMatchKind kind, FcObject object)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.name.object = object;
    vstack->u.name.kind = kind;
    vstack->tag = FcVStackName;
    return FcTrue;
}

static FcBool
FcVStackPushTest (FcConfigParse *parse, FcTest *test)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.test = test;
    vstack->tag = FcVStackTest;
    return FcTrue;
}

static FcBool
FcVStackPushExpr (FcConfigParse *parse, FcVStackTag tag, FcExpr *expr)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.expr = expr;
    vstack->tag = tag;
    return FcTrue;
}

static FcBool
FcVStackPushEdit (FcConfigParse *parse, FcEdit *edit)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.edit = edit;
    vstack->tag = FcVStackEdit;
    return FcTrue;
}

static FcBool
FcVStackPushPattern (FcConfigParse *parse, FcPattern *pattern)
{
    FcVStack    *vstack = FcVStackCreateAndPush (parse);
    if (!vstack)
	return FcFalse;
    vstack->u.pattern = pattern;
    vstack->tag = FcVStackPattern;
    return FcTrue;
}

static FcVStack *
FcVStackFetch (FcConfigParse *parse, int off)
{
    FcVStack    *vstack;

    for (vstack = parse->vstack; vstack && off-- > 0; vstack = vstack->prev);
    return vstack;
}

static FcVStack *
FcVStackPeek (FcConfigParse *parse)
{
    FcVStack	*vstack = parse->vstack;

    return vstack && vstack->pstack == parse->pstack ? vstack : 0;
}

static void
FcVStackPopAndDestroy (FcConfigParse *parse)
{
    FcVStack	*vstack = parse->vstack;

    if (!vstack || vstack->pstack != parse->pstack)
	return;

    parse->vstack = vstack->prev;

    switch (vstack->tag) {
    case FcVStackNone:
	break;
    case FcVStackName:
	break;
    case FcVStackFamily:
	break;
    case FcVStackString:
    case FcVStackConstant:
    case FcVStackGlob:
	FcStrFree (vstack->u.string);
	break;
    case FcVStackPattern:
	FcPatternDestroy (vstack->u.pattern);
	break;
    case FcVStackInteger:
    case FcVStackDouble:
	break;
    case FcVStackMatrix:
	FcExprMatrixFreeShallow (vstack->u.matrix);
	break;
    case FcVStackBool:
	break;
    case FcVStackRange:
	FcRangeDestroy (vstack->u.range);
	break;
    case FcVStackCharSet:
	FcCharSetDestroy (vstack->u.charset);
	break;
    case FcVStackLangSet:
	FcLangSetDestroy (vstack->u.langset);
	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
	free (vstack);
}

static void
FcVStackClear (FcConfigParse *parse)
{
    while (FcVStackPeek (parse))
	FcVStackPopAndDestroy (parse);
}

static int
FcVStackElements (FcConfigParse *parse)
{
    int		h = 0;
    FcVStack	*vstack = parse->vstack;
    while (vstack && vstack->pstack == parse->pstack)
    {
	h++;
	vstack = vstack->prev;
    }
    return h;
}

static FcChar8 **
FcConfigSaveAttr (const XML_Char **attr, FcChar8 **buf, int size_bytes)
{
    int		slen;
    int		i;
    FcChar8	**new;
    FcChar8	*s;

    if (!attr)
	return 0;
    slen = 0;
    for (i = 0; attr[i]; i++)
	slen += strlen ((char *) attr[i]) + 1;
    if (i == 0)
	return 0;
    slen += (i + 1) * sizeof (FcChar8 *);
    if (slen <= size_bytes)
	new = buf;
    else
    {
	new = malloc (slen);
	if (!new)
	{
	    FcConfigMessage (0, FcSevereError, "out of memory");
	    return 0;
	}
    }
    s = (FcChar8 *) (new + (i + 1));
    for (i = 0; attr[i]; i++)
    {
	new[i] = s;
	strcpy ((char *) s, (char *) attr[i]);
	s += strlen ((char *) s) + 1;
    }
    new[i] = 0;
    return new;
}

static FcBool
FcPStackPush (FcConfigParse *parse, FcElement element, const XML_Char **attr)
{
    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;
    }

    new->prev = parse->pstack;
    new->element = element;
    new->attr = FcConfigSaveAttr (attr, new->attr_buf_static, sizeof (new->attr_buf_static));
    FcStrBufInit (&new->str, 0, 0);
    parse->pstack = new;
    return FcTrue;
}

static FcBool
FcPStackPop (FcConfigParse *parse)
{
    FcPStack   *old;

    if (!parse->pstack)
    {
	FcConfigMessage (parse, FcSevereError, "mismatching element");
	return FcFalse;
    }

    /* Don't check the attributes for FcElementNone */
    if (parse->pstack->element != FcElementNone &&
	parse->pstack->attr)
    {
	/* Warn about unused attrs. */
	FcChar8 **attrs = parse->pstack->attr;
	while (*attrs)
	{
	    if (attrs[0][0])
	    {
		FcConfigMessage (parse, FcSevereError, "invalid attribute '%s'", attrs[0]);
	    }
	    attrs += 2;
	}
    }

    FcVStackClear (parse);
    old = parse->pstack;
    parse->pstack = old->prev;
    FcStrBufDestroy (&old->str);

    if (old->attr && old->attr != old->attr_buf_static)
	free (old->attr);

    if (old == &parse->pstack_static[parse->pstack_static_used - 1])
	parse->pstack_static_used--;
    else
	free (old);
    return FcTrue;
}

static FcBool
FcConfigParseInit (FcConfigParse	*parse,
		   const FcChar8	*name,
		   FcConfig		*config,
		   XML_Parser		parser,
		   FcBool		enabled)
{
    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;
    parse->ruleset = FcRuleSetCreate (name);
    parse->parser = parser;
    parse->scanOnly = !enabled;
    FcRuleSetEnable (parse->ruleset, enabled);

    return FcTrue;
}

static void
FcConfigCleanup (FcConfigParse	*parse)
{
    while (parse->pstack)
	FcPStackPop (parse);
    FcRuleSetDestroy (parse->ruleset);
    parse->ruleset = NULL;
}

static const FcChar8 *
FcConfigGetAttribute (FcConfigParse *parse, const char *attr)
{
    FcChar8 **attrs;
    if (!parse->pstack)
	return 0;

    attrs = parse->pstack->attr;
    if (!attrs)
        return 0;

    while (*attrs)
    {
	if (!strcmp ((char *) *attrs, attr))
	{
	    attrs[0][0] = '\0'; /* Mark as used. */
	    return attrs[1];
	}
	attrs += 2;
    }
    return 0;
}

static FcChar8 *
_get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcChar8 *prefix)
{
#ifdef _WIN32
    const FcChar8 *data;
    FcChar8 buffer[1000] = { 0 };
#endif
    FcChar8 *parent = NULL, *retval = NULL;

    if (prefix)
    {
	if (FcStrCmp (prefix, (const FcChar8 *) "xdg") == 0)
	{
	    parent = FcConfigXdgDataHome ();
	    if (!parent)
	    {
		/* Home directory might be disabled */
		return NULL;
	    }
	}
	else if (FcStrCmp (prefix, (const FcChar8 *) "default") == 0 ||
		 FcStrCmp (prefix, (const FcChar8 *) "cwd") == 0)
	{
	    /* Nothing to do */
	}
	else if (FcStrCmp (prefix, (const FcChar8 *) "relative") == 0)
	{
	    parent = FcStrDirname (parse->name);
	    if (!parent)
		return NULL;
	}
    }
#ifndef _WIN32
    /* For Win32, check this later for dealing with special cases */
    else
    {
	if (!FcStrIsAbsoluteFilename (path) && path[0] != '~')
	    FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
    }
    if (parent)
    {
	retval = FcStrBuildFilename (parent, path, NULL);
    }
    else
    {
	retval = FcStrdup (path);
    }
#else
    if (strcmp ((const char *) path, "CUSTOMFONTDIR") == 0)
    {
	FcChar8 *p;
	data = buffer;
	if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
	{
	    FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
	    return NULL;
	}
	/*
	 * 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 ((char *) data, "\\fonts");
    }
    else if (strcmp ((const char *) path, "APPSHAREFONTDIR") == 0)
    {
	FcChar8 *p;
	data = buffer;
	if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
	{
	    FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
	    return NULL;
	}
	p = _mbsrchr (data, '\\');
	if (p) *p = '\0';
	strcat ((char *) data, "\\..\\share\\fonts");
    }
    else if (strcmp ((const char *) path, "WINDOWSFONTDIR") == 0)
    {
	int rc;
	data = buffer;
	rc = pGetSystemWindowsDirectory ((LPSTR) buffer, sizeof (buffer) - 20);
	if (rc == 0 || rc > sizeof (buffer) - 20)
	{
	    FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
	    return NULL;
	}
	if (data [strlen ((const char *) data) - 1] != '\\')
	    strcat ((char *) data, "\\");
	strcat ((char *) data, "fonts");
    }
    else
    {
	data = path;
	if (!prefix)
	{
	    if (!FcStrIsAbsoluteFilename (path) && path[0] != '~')
		FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
	}
	if (parent)
	{
	    retval = FcStrBuildFilename (parent, data, NULL);
	}
	else
	{
	    retval = FcStrdup (data);
	}
    }
#endif

    return retval;
}

static void
FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
{
    FcConfigParse   *parse = userData;
    FcElement	    element;

    element = FcElementMap (name);
    if (element == FcElementUnknown)
	FcConfigMessage (parse, FcSevereWarning, "unknown element \"%s\"", name);

    if (!FcPStackPush (parse, element, attr))
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    return;
}

static void
FcParseRescan (FcConfigParse *parse)
{
    int	    n = FcVStackElements (parse);
    while (n-- > 0)
    {
	FcVStack    *v = FcVStackFetch (parse, n);
	if (v->tag != FcVStackInteger)
	    FcConfigMessage (parse, FcSevereWarning, "non-integer rescan");
	else
	    parse->config->rescanInterval = v->u.integer;
    }
}

static void
FcParseInt (FcConfigParse *parse)
{
    FcChar8 *s, *end;
    int	    l;

    if (!parse->pstack)
	return;
    s = FcStrBufDoneStatic (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    end = 0;
    l = (int) strtol ((char *) s, (char **)&end, 0);
    if (end != s + strlen ((char *) s))
	FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid integer", s);
    else
	FcVStackPushInteger (parse, l);
    FcStrBufDestroy (&parse->pstack->str);
}

/*
 * idea copied from glib g_ascii_strtod with
 * permission of the author (Alexander Larsson)
 */

#include <locale.h>

static double
FcStrtod (char *s, char **end)
{
#ifndef __BIONIC__
    struct lconv    *locale_data;
#endif
    const char	    *decimal_point;
    int		    dlen;
    char	    *dot;
    double	    v;

    /*
     * Have to swap the decimal point to match the current locale
     * if that locale doesn't use 0x2e
     */
#ifndef __BIONIC__
    locale_data = localeconv ();
    decimal_point = locale_data->decimal_point;
    dlen = strlen (decimal_point);
#else
    decimal_point = ".";
    dlen = 1;
#endif

    if ((dot = strchr (s, 0x2e)) &&
	(decimal_point[0] != 0x2e ||
	 decimal_point[1] != 0))
    {
	char	buf[128];
	int	slen = strlen (s);
	
	if (slen + dlen > (int) sizeof (buf))
	{
	    if (end)
		*end = s;
	    v = 0;
	}
	else
	{
	    char	*buf_end;
	    /* mantissa */
	    strncpy (buf, s, dot - s);
	    /* decimal point */
	    strcpy (buf + (dot - s), decimal_point);
	    /* rest of number */
	    strcpy (buf + (dot - s) + dlen, dot + 1);
	    buf_end = 0;
	    v = strtod (buf, &buf_end);
	    if (buf_end) {
		buf_end = s + (buf_end - buf);
		if (buf_end > dot)
		    buf_end -= dlen - 1;
	    }
	    if (end)
		*end = buf_end;
	}
    }
    else
	v = strtod (s, end);
    return v;
}

static void
FcParseDouble (FcConfigParse *parse)
{
    FcChar8 *s, *end;
    double  d;

    if (!parse->pstack)
	return;
    s = FcStrBufDoneStatic (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    end = 0;
    d = FcStrtod ((char *) s, (char **)&end);
    if (end != s + strlen ((char *) s))
	FcConfigMessage (parse, FcSevereError, "\"%s\": not a valid double", s);
    else
	FcVStackPushDouble (parse, d);
    FcStrBufDestroy (&parse->pstack->str);
}

static void
FcParseString (FcConfigParse *parse, FcVStackTag tag)
{
    FcChar8 *s;

    if (!parse->pstack)
	return;
    s = FcStrBufDone (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    if (!FcVStackPushString (parse, tag, s))
	FcStrFree (s);
}

static void
FcParseName (FcConfigParse *parse)
{
    const FcChar8   *kind_string;
    FcMatchKind	    kind;
    FcChar8 *s;
    FcObject object;

    kind_string = FcConfigGetAttribute (parse, "target");
    if (!kind_string)
	kind = FcMatchDefault;
    else
    {
	if (!strcmp ((char *) kind_string, "pattern"))
	    kind = FcMatchPattern;
	else if (!strcmp ((char *) kind_string, "font"))
	    kind = FcMatchFont;
	else if (!strcmp ((char *) kind_string, "default"))
	    kind = FcMatchDefault;
	else
	{
	    FcConfigMessage (parse, FcSevereWarning, "invalid name target \"%s\"", kind_string);
	    return;
	}
    }

    if (!parse->pstack)
	return;
    s = FcStrBufDone (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    object = FcObjectFromName ((const char *) s);

    FcVStackPushName (parse, kind, object);

    FcStrFree (s);
}

static void
FcParseMatrix (FcConfigParse *parse)
{
    FcExprMatrix m;

    m.yy = FcPopExpr (parse);
    m.yx = FcPopExpr (parse);
    m.xy = FcPopExpr (parse);
    m.xx = FcPopExpr (parse);

    if (!m.yy || !m.yx || !m.xy || !m.xx)
    {
	FcConfigMessage (parse, FcSevereWarning, "Missing values in matrix element");
	return;
    }
    if (FcPopExpr (parse))
      FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements");
    else
      FcVStackPushMatrix (parse, &m);
}

static void
FcParseRange (FcConfigParse *parse)
{
    FcVStack	*vstack;
    FcRange	*r;
    FcChar32	n[2] = {0, 0};
    int		count = 1;
    double	d[2] = {0.0L, 0.0L};
    FcBool	dflag = FcFalse;

    while ((vstack = FcVStackPeek (parse)))
    {
	if (count < 0)
	{
	    FcConfigMessage (parse, FcSevereError, "too many elements in range");
	    return;
	}
	switch ((int) vstack->tag) {
	case FcVStackInteger:
	    if (dflag)
		d[count] = (double)vstack->u.integer;
	    else
		n[count] = vstack->u.integer;
	    break;
	case FcVStackDouble:
	    if (count == 0 && !dflag)
		d[1] = (double)n[1];
	    d[count] = vstack->u._double;
	    dflag = FcTrue;
	    break;
	default:
	    FcConfigMessage (parse, FcSevereError, "invalid element in range");
	    if (dflag)
		d[count] = 0.0L;
	    else
		n[count] = 0;
	    break;
	}
	count--;
	FcVStackPopAndDestroy (parse);
    }
    if (count >= 0)
    {
	FcConfigMessage (parse, FcSevereError, "invalid range");
	return;
    }
    if (dflag)
    {
	if (d[0] > d[1])
	{
	    FcConfigMessage (parse, FcSevereError, "invalid range");
	    return;
	}
	r = FcRangeCreateDouble (d[0], d[1]);
    }
    else
    {
	if (n[0] > n[1])
	{
	    FcConfigMessage (parse, FcSevereError, "invalid range");
	    return;
	}
	r = FcRangeCreateInteger (n[0], n[1]);
    }
    FcVStackPushRange (parse, r);
}

static FcBool
FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_)
{
    FcBool  result = FcFalse;

    if (!FcNameBool (bool_, &result))
	FcConfigMessage (parse, FcSevereWarning, "\"%s\" is not known boolean",
			 bool_);
    return result;
}

static void
FcParseBool (FcConfigParse *parse)
{
    FcChar8 *s;

    if (!parse->pstack)
	return;
    s = FcStrBufDoneStatic (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    FcVStackPushBool (parse, FcConfigLexBool (parse, s));
    FcStrBufDestroy (&parse->pstack->str);
}

static void
FcParseCharSet (FcConfigParse *parse)
{
    FcVStack	*vstack;
    FcCharSet	*charset = FcCharSetCreate ();
    FcChar32	i, begin, end;
    int n = 0;

    while ((vstack = FcVStackPeek (parse)))
    {
	switch ((int) vstack->tag) {
	case FcVStackInteger:
	    if (!FcCharSetAddChar (charset, vstack->u.integer))
	    {
		FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", vstack->u.integer);
	    }
	    else
		n++;
	    break;
	case FcVStackRange:
	    begin = (FcChar32) vstack->u.range->begin;
	    end = (FcChar32) vstack->u.range->end;

	    if (begin <= end)
	    {
	      for (i = begin; i <= end; i++)
	      {
		  if (!FcCharSetAddChar (charset, i))
		  {
		      FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
		  }
		  else
		      n++;
	      }
	    }
	    break;
	default:
		FcConfigMessage (parse, FcSevereError, "invalid element in charset");
		break;
	}
	FcVStackPopAndDestroy (parse);
    }
    if (n > 0)
	    FcVStackPushCharSet (parse, charset);
    else
	    FcCharSetDestroy (charset);
}

static void
FcParseLangSet (FcConfigParse *parse)
{
    FcVStack	*vstack;
    FcLangSet	*langset = FcLangSetCreate ();
    int n = 0;

    while ((vstack = FcVStackPeek (parse)))
    {
	switch ((int) vstack->tag) {
	case FcVStackString:
	    if (!FcLangSetAdd (langset, vstack->u.string))
	    {
		FcConfigMessage (parse, FcSevereWarning, "invalid langset: %s", vstack->u.string);
	    }
	    else
		n++;
	    break;
	default:
		FcConfigMessage (parse, FcSevereError, "invalid element in langset");
		break;
	}
	FcVStackPopAndDestroy (parse);
    }
    if (n > 0)
	    FcVStackPushLangSet (parse, langset);
    else
	    FcLangSetDestroy (langset);
}

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)
{
    FcVStack	*vstack;
    FcExpr	*left, *expr = 0, *new;

    while ((vstack = FcVStackPeek (parse)))
    {
	if (vstack->tag != FcVStackFamily)
	{
	    FcConfigMessage (parse, FcSevereWarning, "non-family");
	    FcVStackPopAndDestroy (parse);
	    continue;
	}
	left = vstack->u.expr;
	vstack->tag = FcVStackNone;
	FcVStackPopAndDestroy (parse);
	if (expr)
	{
	    new = FcExprCreateOp (parse->config, left, FcOpComma, expr);
	    if (!new)
	    {
		FcConfigMessage (parse, FcSevereError, "out of memory");
		FcExprDestroy (left);
		FcExprDestroy (expr);
		break;
	    }
	    expr = new;
	}
	else
	    expr = left;
    }
    if (expr)
    {
	if (!FcVStackPushExpr (parse, tag, expr))
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
            FcExprDestroy (expr);
	}
    }
}

static void
FcParseFamily (FcConfigParse *parse)
{
    FcChar8 *s;
    FcExpr  *expr;

    if (!parse->pstack)
	return;
    s = FcStrBufDoneStatic (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    expr = FcExprCreateString (parse->config, s);
    FcStrBufDestroy (&parse->pstack->str);
    if (expr)
	FcVStackPushExpr (parse, FcVStackFamily, expr);
}

static void
FcParseAlias (FcConfigParse *parse)
{
    FcExpr	*family = 0, *accept = 0, *prefer = 0, *def = 0, *new = 0;
    FcEdit	*edit = 0;
    FcVStack	*vstack;
    FcRule	*rule = NULL, *r;
    FcValueBinding  binding;
    int		    n;

    if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding))
	return;
    while ((vstack = FcVStackPeek (parse)))
    {
	switch ((int) vstack->tag) {
	case FcVStackFamily:
	    if (family)
	    {
		FcConfigMessage (parse, FcSevereWarning, "Having multiple <family> in <alias> isn't supported and may not work as expected");
		new = FcExprCreateOp (parse->config, vstack->u.expr, FcOpComma, family);
		if (!new)
		    FcConfigMessage (parse, FcSevereError, "out of memory");
		else
		    family = new;
	    }
	    else
		new = vstack->u.expr;
	    if (new)
	    {
		family = new;
		vstack->tag = FcVStackNone;
	    }
	    break;
	case FcVStackPrefer:
	    if (prefer)
		FcExprDestroy (prefer);
	    prefer = vstack->u.expr;
	    vstack->tag = FcVStackNone;
	    break;
	case FcVStackAccept:
	    if (accept)
		FcExprDestroy (accept);
	    accept = vstack->u.expr;
	    vstack->tag = FcVStackNone;
	    break;
	case FcVStackDefault:
	    if (def)
		FcExprDestroy (def);
	    def = vstack->u.expr;
	    vstack->tag = FcVStackNone;
	    break;
	case FcVStackTest:
	    if (rule)
	    {
		r = FcRuleCreate (FcRuleTest, vstack->u.test);
		r->next = rule;
		rule = r;
	    }
	    else
		rule = FcRuleCreate (FcRuleTest, vstack->u.test);
	    vstack->tag = FcVStackNone;
	    break;
	default:
	    FcConfigMessage (parse, FcSevereWarning, "bad alias");
	    break;
	}
	FcVStackPopAndDestroy (parse);
    }
    if (!family)
    {
	FcConfigMessage (parse, FcSevereError, "missing family in alias");
	if (prefer)
	    FcExprDestroy (prefer);
	if (accept)
	    FcExprDestroy (accept);
	if (def)
	    FcExprDestroy (def);
	if (rule)
	    FcRuleDestroy (rule);
	return;
    }
    if (!prefer &&
	!accept &&
	!def)
    {
	FcExprDestroy (family);
	if (rule)
	    FcRuleDestroy (rule);
	return;
    }
    else
    {
	FcTest *t = FcTestCreate (parse, FcMatchPattern,
				  FcQualAny,
				  (FcChar8 *) FC_FAMILY,
				  FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks),
				  family);
	if (rule)
	{
	    for (r = rule; r->next; r = r->next);
	    r->next = FcRuleCreate (FcRuleTest, t);
	    r = r->next;
	}
	else
	{
	    r = rule = FcRuleCreate (FcRuleTest, t);
	}
    }
    if (prefer)
    {
	edit = FcEditCreate (parse,
			     FC_FAMILY_OBJECT,
			     FcOpPrepend,
			     prefer,
			     binding);
	if (!edit)
	    FcExprDestroy (prefer);
	else
	{
	    r->next = FcRuleCreate (FcRuleEdit, edit);
	    r = r->next;
	}
    }
    if (accept)
    {
	edit = FcEditCreate (parse,
			     FC_FAMILY_OBJECT,
			     FcOpAppend,
			     accept,
			     binding);
	if (!edit)
	    FcExprDestroy (accept);
	else
	{
	    r->next = FcRuleCreate (FcRuleEdit, edit);
	    r = r->next;
	}
    }
    if (def)
    {
	edit = FcEditCreate (parse,
			     FC_FAMILY_OBJECT,
			     FcOpAppendLast,
			     def,
			     binding);
	if (!edit)
	    FcExprDestroy (def);
	else
	{
	    r->next = FcRuleCreate (FcRuleEdit, edit);
	    r = r->next;
	}
    }
    if ((n = FcRuleSetAdd (parse->ruleset, rule, FcMatchPattern)) == -1)
	FcRuleDestroy (rule);
    else
	if (parse->config->maxObjects < n)
	    parse->config->maxObjects = n;
}

static void
FcParseDescription (FcConfigParse *parse)
{
    const FcChar8 *domain;
    FcChar8 *desc;

    domain = FcConfigGetAttribute (parse, "domain");
    desc = FcStrBufDone (&parse->pstack->str);
    if (!desc)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    FcRuleSetAddDescription (parse->ruleset, domain, desc);

    FcStrFree (desc);
}

static void
FcParseRemapDir (FcConfigParse *parse)
{
    const FcChar8 *path, *attr, *data, *salt;
    FcChar8 *prefix = NULL;

    data = FcStrBufDoneStatic (&parse->pstack->str);
    if (!data)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    if (data[0] == 0)
    {
	FcConfigMessage (parse, FcSevereWarning, "empty font directory name for remap ignored");
	return;
    }
    path = FcConfigGetAttribute (parse, "as-path");
    if (!path)
    {
	FcConfigMessage (parse, FcSevereWarning, "Missing as-path in remap-dir");
	return;
    }
    attr = FcConfigGetAttribute (parse, "prefix");
    salt = FcConfigGetAttribute (parse, "salt");
    prefix = _get_real_path_from_prefix (parse, data, attr);
    if (!prefix || prefix[0] == 0)
    {
	/* nop */
    }
    else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ()))
    {
	if (!FcConfigAddFontDir (parse->config, prefix, path, salt))
	    FcConfigMessage (parse, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path);
    }
    FcStrBufDestroy (&parse->pstack->str);

    if (prefix)
	FcStrFree (prefix);
}

static void
FcParseResetDirs (FcConfigParse *parse)
{
    if (!parse->scanOnly)
    {
	if (!FcConfigResetFontDirs (parse->config))
	    FcConfigMessage (parse, FcSevereError, "Unable to reset fonts dirs");
    }
}

static FcExpr *
FcPopExpr (FcConfigParse *parse)
{
    FcVStack	*vstack = FcVStackPeek (parse);
    FcExpr	*expr = 0;
    if (!vstack)
	return 0;
    switch ((int) vstack->tag) {
    case FcVStackNone:
	break;
    case FcVStackString:
    case FcVStackFamily:
	expr = FcExprCreateString (parse->config, vstack->u.string);
	break;
    case FcVStackName:
	expr = FcExprCreateName (parse->config, vstack->u.name);
	break;
    case FcVStackConstant:
	expr = FcExprCreateConst (parse->config, vstack->u.string);
	break;
    case FcVStackGlob:
	/* XXX: What's the correct action here? (CDW) */
	break;
    case FcVStackPrefer:
    case FcVStackAccept:
    case FcVStackDefault:
	expr = vstack->u.expr;
	vstack->tag = FcVStackNone;
	break;
    case FcVStackInteger:
	expr = FcExprCreateInteger (parse->config, vstack->u.integer);
	break;
    case FcVStackDouble:
	expr = FcExprCreateDouble (parse->config, vstack->u._double);
	break;
    case FcVStackMatrix:
	expr = FcExprCreateMatrix (parse->config, vstack->u.matrix);
	break;
    case FcVStackRange:
	expr = FcExprCreateRange (parse->config, vstack->u.range);
	break;
    case FcVStackBool:
	expr = FcExprCreateBool (parse->config, vstack->u.bool_);
	break;
    case FcVStackCharSet:
	expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
	break;
    case FcVStackLangSet:
	expr = FcExprCreateLangSet (parse->config, vstack->u.langset);
	break;
    case FcVStackTest:
	break;
    case FcVStackExpr:
	expr = vstack->u.expr;
	vstack->tag = FcVStackNone;
	break;
    case FcVStackEdit:
	break;
    default:
	break;
    }
    FcVStackPopAndDestroy (parse);
    return expr;
}

/*
 * This builds a tree of binary operations.  Note
 * that every operator is defined so that if only
 * a single operand is contained, the value of the
 * whole expression is the value of the operand.
 *
 * This code reduces in that case to returning that
 * operand.
 */
static FcExpr *
FcPopBinary (FcConfigParse *parse, FcOp op)
{
    FcExpr  *left, *expr = 0, *new;

    while ((left = FcPopExpr (parse)))
    {
	if (expr)
	{
	    new = FcExprCreateOp (parse->config, left, op, expr);
	    if (!new)
	    {
		FcConfigMessage (parse, FcSevereError, "out of memory");
		FcExprDestroy (left);
		FcExprDestroy (expr);
		return 0;
	    }
	    expr = new;
	}
	else
	    expr = left;
    }
    return expr;
}

static void
FcParseBinary (FcConfigParse *parse, FcOp op)
{
    FcExpr  *expr = FcPopBinary (parse, op);
    if (expr)
	FcVStackPushExpr (parse, FcVStackExpr, expr);
}

/*
 * This builds a a unary operator, it consumes only
 * a single operand
 */

static FcExpr *
FcPopUnary (FcConfigParse *parse, FcOp op)
{
    FcExpr  *operand, *new = 0;

    if ((operand = FcPopExpr (parse)))
    {
	new = FcExprCreateOp (parse->config, operand, op, 0);
	if (!new)
	{
	    FcExprDestroy (operand);
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	}
    }
    return new;
}

static void
FcParseUnary (FcConfigParse *parse, FcOp op)
{
    FcExpr  *expr = FcPopUnary (parse, op);
    if (expr)
	FcVStackPushExpr (parse, FcVStackExpr, expr);
}

static void
FcParseDir (FcConfigParse *parse)
{
    const FcChar8 *attr, *data, *salt;
    FcChar8 *prefix = NULL;

    data = FcStrBufDoneStatic (&parse->pstack->str);
    if (!data)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    if (data[0] == 0)
    {
	FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored");
	return;
    }
    attr = FcConfigGetAttribute (parse, "prefix");
    salt = FcConfigGetAttribute (parse, "salt");
    prefix = _get_real_path_from_prefix (parse, data, attr);
    if (!prefix || prefix[0] == 0)
    {
	/* nop */
    }
    else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ()))
    {
	if (!FcConfigAddFontDir (parse->config, prefix, NULL, salt))
	    FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", prefix);
    }
    FcStrBufDestroy (&parse->pstack->str);

    if (prefix)
	FcStrFree (prefix);
}

static void
FcParseCacheDir (FcConfigParse *parse)
{
    const FcChar8 *attr;
    FcChar8 *prefix = NULL, *p, *data = NULL;

    attr = FcConfigGetAttribute (parse, "prefix");
    if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
    {
	prefix = FcConfigXdgCacheHome ();
	/* home directory might be disabled.
	 * simply ignore this element.
	 */
	if (!prefix)
	    goto bail;
    }
    data = FcStrBufDone (&parse->pstack->str);
    if (!data)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	data = prefix;
	goto bail;
    }
    if (prefix)
    {
	size_t plen = strlen ((const char *)prefix);
	size_t dlen = strlen ((const char *)data);

	p = realloc (prefix, plen + 1 + dlen + 1);
	if (!p)
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	    FcStrFree (prefix);
	    goto bail;
	}
	prefix = p;
	prefix[plen] = FC_DIR_SEPARATOR;
	memcpy (&prefix[plen + 1], data, dlen);
	prefix[plen + 1 + dlen] = 0;
	FcStrFree (data);
	data = prefix;
    }
#ifdef _WIN32
    else if (data[0] == '/' && fontconfig_instprefix[0] != '\0')
    {
	size_t plen = strlen ((const char *)fontconfig_instprefix);
	size_t dlen = strlen ((const char *)data);

	prefix = malloc (plen + 1 + dlen + 1);
	if (!prefix)
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	    goto bail;
	}
	strcpy ((char *) prefix, (char *) fontconfig_instprefix);
	prefix[plen] = FC_DIR_SEPARATOR;
	memcpy (&prefix[plen + 1], data, dlen);
	prefix[plen + 1 + dlen] = 0;
	FcStrFree (data);
	data = prefix;
    }
    else if (strcmp ((const char *) data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0)
    {
	int rc;

	FcStrFree (data);
	data = malloc (1000);
	if (!data)
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	    goto bail;
	}
	rc = GetTempPath (800, (LPSTR) data);
	if (rc == 0 || rc > 800)
	{
	    FcConfigMessage (parse, FcSevereError, "GetTempPath failed");
	    goto bail;
	}
	if (data [strlen ((const char *) data) - 1] != '\\')
	    strcat ((char *) data, "\\");
	strcat ((char *) data, "fontconfig\\cache");
    }
    else if (strcmp ((const char *) data, "LOCAL_APPDATA_FONTCONFIG_CACHE") == 0)
    {
	char szFPath[MAX_PATH + 1];
	size_t len;

	if (!(pSHGetFolderPathA && SUCCEEDED(pSHGetFolderPathA(NULL, /* CSIDL_LOCAL_APPDATA */ 28, NULL, 0, szFPath))))
	{
	    FcConfigMessage (parse, FcSevereError, "SHGetFolderPathA failed");
	    goto bail;
	}
	strncat(szFPath, "\\fontconfig\\cache", MAX_PATH - 1 - strlen(szFPath));
	len = strlen(szFPath) + 1;
	FcStrFree (data);
	data = malloc(len);
	if (!data)
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	    goto bail;
	}
	strncpy((char *) data, szFPath, len);
    }
#endif
    if (strlen ((char *) data) == 0)
	FcConfigMessage (parse, FcSevereWarning, "empty cache directory name ignored");
    else if (!parse->scanOnly && (!FcStrUsesHome (data) || FcConfigHome ()))
    {
	if (!FcConfigAddCacheDir (parse->config, data))
	    FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data);
    }
    FcStrBufDestroy (&parse->pstack->str);

  bail:
    if (data)
	FcStrFree (data);
}

void
FcConfigPathFini (void)
{
    FcChar8 *s;

retry_dir:
    s = fc_atomic_ptr_get (&__fc_userdir);
    if (!fc_atomic_ptr_cmpexch (&__fc_userdir, s, NULL))
	goto retry_dir;
    free (s);

retry_conf:
    s = fc_atomic_ptr_get (&__fc_userconf);
    if (!fc_atomic_ptr_cmpexch (&__fc_userconf, s, NULL))
	goto retry_conf;
    free (s);
}

static void
FcParseInclude (FcConfigParse *parse)
{
    FcChar8	    *s;
    const FcChar8   *attr;
    FcBool	    ignore_missing = FcFalse;
#ifndef _WIN32
    FcBool	    deprecated = FcFalse;
#endif
    FcChar8	    *prefix = NULL, *p;
    FcChar8	    *userdir = NULL, *userconf = NULL;
    FcRuleSet	    *ruleset;
    FcMatchKind	    k;

    s = FcStrBufDoneStatic (&parse->pstack->str);
    if (!s)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	goto bail;
    }
    attr = FcConfigGetAttribute (parse, "ignore_missing");
    if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
	ignore_missing = FcTrue;
    attr = FcConfigGetAttribute (parse, "deprecated");
#ifndef _WIN32
    if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
        deprecated = FcTrue;
#endif
    attr = FcConfigGetAttribute (parse, "prefix");
    if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
    {
	prefix = FcConfigXdgConfigHome ();
	/* home directory might be disabled.
	 * simply ignore this element.
	 */
	if (!prefix)
	    goto bail;
    }
    if (prefix)
    {
	size_t plen = strlen ((const char *)prefix);
	size_t dlen = strlen ((const char *)s);
	FcChar8 *u;

	p = realloc (prefix, plen + 1 + dlen + 1);
	if (!p)
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	    goto bail;
	}
	prefix = p;
	prefix[plen] = FC_DIR_SEPARATOR;
	memcpy (&prefix[plen + 1], s, dlen);
	prefix[plen + 1 + dlen] = 0;
	s = prefix;
	if (FcFileIsDir (s))
	{
	userdir:
	    userdir = fc_atomic_ptr_get (&__fc_userdir);
	    if (!userdir)
	    {
		u = FcStrdup (s);
		if (!fc_atomic_ptr_cmpexch (&__fc_userdir, userdir, u))
		{
		    free (u);
		    goto userdir;
		}
		userdir = u;
	    }
	}
	else if (FcFileIsFile (s))
	{
	userconf:
	    userconf = fc_atomic_ptr_get (&__fc_userconf);
	    if (!userconf)
	    {
		u = FcStrdup (s);
		if (!fc_atomic_ptr_cmpexch (&__fc_userconf, userconf, u))
		{
		    free (u);
		    goto userconf;
		}
		userconf = u;
	    }
	}
	else
	{
	    /* No config dir nor file on the XDG directory spec compliant place
	     * so need to guess what it is supposed to be.
	     */
	    if (FcStrStr (s, (const FcChar8 *)"conf.d") != NULL)
		goto userdir;
	    else
		goto userconf;
	}
    }
    /* flush the ruleset into the queue */
    ruleset = parse->ruleset;
    parse->ruleset = FcRuleSetCreate (ruleset->name);
    FcRuleSetEnable (parse->ruleset, ruleset->enabled);
    FcRuleSetAddDescription (parse->ruleset, ruleset->domain, ruleset->description);
    for (k = FcMatchKindBegin; k < FcMatchKindEnd; k++)
    {
	FcPtrListIter iter;

	FcPtrListIterInit (ruleset->subst[k], &iter);
	if (FcPtrListIterIsValid (ruleset->subst[k], &iter))
	{
	    FcPtrListIterInitAtLast (parse->config->subst[k], &iter);
	    FcRuleSetReference (ruleset);
	    FcPtrListIterAdd (parse->config->subst[k], &iter, ruleset);
	}
    }
    FcRuleSetDestroy (ruleset);
    if (!_FcConfigParse (parse->config, s, !ignore_missing, !parse->scanOnly))
	parse->error = FcTrue;
#ifndef _WIN32
    else
    {
        FcChar8 *filename;
	static FcBool warn_conf = FcFalse, warn_confd = FcFalse;

        filename = FcConfigFilename(s);
	if (deprecated == FcTrue &&
	    filename != NULL &&
	    userdir != NULL &&
	    !FcFileIsLink (filename))
	{
	    if (FcFileIsDir (filename))
	    {
		FcChar8 *parent = FcStrDirname (userdir);

		if (!FcFileIsDir (parent))
		    FcMakeDirectory (parent);
		FcStrFree (parent);
		if (FcFileIsDir (userdir) ||
		    rename ((const char *)filename, (const char *)userdir) != 0 ||
		    symlink ((const char *)userdir, (const char *)filename) != 0)
		{
		    if (!warn_confd)
		    {
			FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir);
			warn_confd = FcTrue;
		    }
		}
	    }
	    else
	    {
		FcChar8 *parent = FcStrDirname (userconf);

		if (!FcFileIsDir (parent))
		    FcMakeDirectory (parent);
		FcStrFree (parent);
		if (FcFileIsFile (userconf) ||
		    rename ((const char *)filename, (const char *)userconf) != 0 ||
		    symlink ((const char *)userconf, (const char *)filename) != 0)
		{
		    if (!warn_conf)
		    {
			FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf);
			warn_conf = FcTrue;
		    }
		}
	    }
        }
        if(filename)
            FcStrFree(filename);
    }
#endif
    FcStrBufDestroy (&parse->pstack->str);

  bail:
    if (prefix)
	FcStrFree (prefix);
}

typedef struct _FcOpMap {
    char    name[16];
    FcOp    op;
} FcOpMap;

static FcOp
FcConfigLexOp (const FcChar8 *op, const FcOpMap	*map, int nmap)
{
    int	i;

    for (i = 0; i < nmap; i++)
	if (!strcmp ((char *) op, map[i].name))
	    return map[i].op;
    return FcOpInvalid;
}

static const FcOpMap fcCompareOps[] = {
    { "eq",		FcOpEqual	    },
    { "not_eq",		FcOpNotEqual	    },
    { "less",		FcOpLess	    },
    { "less_eq",	FcOpLessEqual	    },
    { "more",		FcOpMore	    },
    { "more_eq",	FcOpMoreEqual	    },
    { "contains",	FcOpContains	    },
    { "not_contains",	FcOpNotContains	    }
};

#define NUM_COMPARE_OPS	(int) (sizeof fcCompareOps / sizeof fcCompareOps[0])

static FcOp
FcConfigLexCompare (const FcChar8 *compare)
{
    return FcConfigLexOp (compare, fcCompareOps, NUM_COMPARE_OPS);
}

static void
FcParseTest (FcConfigParse *parse)
{
    const FcChar8   *kind_string;
    FcMatchKind	    kind;
    const FcChar8   *qual_string;
    FcQual	    qual;
    const FcChar8   *name;
    const FcChar8   *compare_string;
    FcOp	    compare;
    FcExpr	    *expr;
    FcTest	    *test;
    const FcChar8   *iblanks_string;
    int              flags = 0;

    kind_string = FcConfigGetAttribute (parse, "target");
    if (!kind_string)
	kind = FcMatchDefault;
    else
    {
	if (!strcmp ((char *) kind_string, "pattern"))
	    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
	{
	    FcConfigMessage (parse, FcSevereWarning, "invalid test target \"%s\"", kind_string);
	    return;
	}
    }
    qual_string = FcConfigGetAttribute (parse, "qual");
    if (!qual_string)
	qual = FcQualAny;
    else
    {
	if (!strcmp ((char *) qual_string, "any"))
	    qual = FcQualAny;
	else if (!strcmp ((char *) qual_string, "all"))
	    qual = FcQualAll;
	else if (!strcmp ((char *) qual_string, "first"))
	    qual = FcQualFirst;
	else if (!strcmp ((char *) qual_string, "not_first"))
	    qual = FcQualNotFirst;
	else
	{
	    FcConfigMessage (parse, FcSevereWarning, "invalid test qual \"%s\"", qual_string);
	    return;
	}
    }
    name = FcConfigGetAttribute (parse, "name");
    if (!name)
    {
	FcConfigMessage (parse, FcSevereWarning, "missing test name");
	return;
    }
    compare_string = FcConfigGetAttribute (parse, "compare");
    if (!compare_string)
	compare = FcOpEqual;
    else
    {
	compare = FcConfigLexCompare (compare_string);
	if (compare == FcOpInvalid)
	{
	    FcConfigMessage (parse, FcSevereWarning, "invalid test compare \"%s\"", compare_string);
	    return;
	}
    }
    iblanks_string = FcConfigGetAttribute (parse, "ignore-blanks");
    if (iblanks_string)
    {
	FcBool f = FcFalse;

	if (!FcNameBool (iblanks_string, &f))
	{
	    FcConfigMessage (parse,
			     FcSevereWarning,
			     "invalid test ignore-blanks \"%s\"", iblanks_string);
	}
	if (f)
	    flags |= FcOpFlagIgnoreBlanks;
    }
    expr = FcPopBinary (parse, FcOpComma);
    if (!expr)
    {
	FcConfigMessage (parse, FcSevereWarning, "missing test expression");
	return;
    }
    if (expr->op == FcOpComma)
    {
	FcConfigMessage (parse, FcSevereWarning, "Having multiple values in <test> isn't supported and may not work as expected");
    }
    test = FcTestCreate (parse, kind, qual, name, FC_OP (compare, flags), expr);
    if (!test)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
    FcVStackPushTest (parse, test);
}

static const FcOpMap fcModeOps[] = {
    { "assign",		FcOpAssign	    },
    { "assign_replace",	FcOpAssignReplace   },
    { "prepend",	FcOpPrepend	    },
    { "prepend_first",	FcOpPrependFirst    },
    { "append",		FcOpAppend	    },
    { "append_last",	FcOpAppendLast	    },
    { "delete",		FcOpDelete	    },
    { "delete_all",	FcOpDeleteAll	    },
};

#define NUM_MODE_OPS (int) (sizeof fcModeOps / sizeof fcModeOps[0])

static FcOp
FcConfigLexMode (const FcChar8 *mode)
{
    return FcConfigLexOp (mode, fcModeOps, NUM_MODE_OPS);
}

static void
FcParseEdit (FcConfigParse *parse)
{
    const FcChar8   *name;
    const FcChar8   *mode_string;
    FcOp	    mode;
    FcValueBinding  binding;
    FcExpr	    *expr;
    FcEdit	    *edit;

    name = FcConfigGetAttribute (parse, "name");
    if (!name)
    {
	FcConfigMessage (parse, FcSevereWarning, "missing edit name");
	return;
    }
    mode_string = FcConfigGetAttribute (parse, "mode");
    if (!mode_string)
	mode = FcOpAssign;
    else
    {
	mode = FcConfigLexMode (mode_string);
	if (mode == FcOpInvalid)
	{
	    FcConfigMessage (parse, FcSevereWarning, "invalid edit mode \"%s\"", mode_string);
	    return;
	}
    }
    if (!FcConfigLexBinding (parse, FcConfigGetAttribute (parse, "binding"), &binding))
	return;

    expr = FcPopBinary (parse, FcOpComma);
    if ((mode == FcOpDelete || mode == FcOpDeleteAll) &&
	expr != NULL)
    {
	FcConfigMessage (parse, FcSevereWarning, "Expression doesn't take any effects for delete and delete_all");
	FcExprDestroy (expr);
	expr = NULL;
    }
    edit = FcEditCreate (parse, FcObjectFromName ((char *) name),
			 mode, expr, binding);
    if (!edit)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	FcExprDestroy (expr);
	return;
    }
    if (!FcVStackPushEdit (parse, edit))
	FcEditDestroy (edit);
}

static void
FcParseMatch (FcConfigParse *parse)
{
    const FcChar8   *kind_name;
    FcMatchKind	    kind;
    FcVStack	    *vstack;
    FcRule	    *rule = NULL, *r;
    int		    n;

    kind_name = FcConfigGetAttribute (parse, "target");
    if (!kind_name)
	kind = FcMatchPattern;
    else
    {
	if (!strcmp ((char *) kind_name, "pattern"))
	    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);
	    return;
	}
    }
    while ((vstack = FcVStackPeek (parse)))
    {
	switch ((int) vstack->tag) {
	case FcVStackTest:
	    r = FcRuleCreate (FcRuleTest, vstack->u.test);
	    if (rule)
		r->next = rule;
	    rule = r;
	    vstack->tag = FcVStackNone;
	    break;
	case FcVStackEdit:
	    if (kind == FcMatchScan && vstack->u.edit->object > FC_MAX_BASE_OBJECT)
	    {
		FcConfigMessage (parse, FcSevereError,
				 "<match target=\"scan\"> cannot edit user-defined object \"%s\"",
				 FcObjectName(vstack->u.edit->object));
		if (rule)
		    FcRuleDestroy (rule);
		return;
	    }
	    r = FcRuleCreate (FcRuleEdit, vstack->u.edit);
	    if (rule)
		r->next = rule;
	    rule = r;
	    vstack->tag = FcVStackNone;
	    break;
	default:
	    FcConfigMessage (parse, FcSevereWarning, "invalid match element");
	    break;
	}
	FcVStackPopAndDestroy (parse);
    }
    if (!rule)
    {
	FcConfigMessage (parse, FcSevereWarning, "No <test> nor <edit> elements in <match>");
	return;
    }
    if ((n = FcRuleSetAdd (parse->ruleset, rule, kind)) == -1)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	FcRuleDestroy (rule);
    }
    else
	if (parse->config->maxObjects < n)
	    parse->config->maxObjects = n;
}

static void
FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
{
    FcVStack	*vstack;

    while ((vstack = FcVStackPeek (parse)))
    {
	switch ((int) vstack->tag) {
	case FcVStackGlob:
	    if (!parse->scanOnly && !FcConfigGlobAdd (parse->config,
						      vstack->u.string,
						      element == FcElementAcceptfont))
	    {
		FcConfigMessage (parse, FcSevereError, "out of memory");
	    }
	    else
	    {
		if (parse->scanOnly && vstack->u.string)
		{
		    FcStrFree (vstack->u.string);
		    vstack->tag = FcVStackNone;
		}
	    }
	    break;
	case FcVStackPattern:
	    if (!parse->scanOnly && !FcConfigPatternsAdd (parse->config,
							  vstack->u.pattern,
							  element == FcElementAcceptfont))
	    {
		FcConfigMessage (parse, FcSevereError, "out of memory");
	    }
	    else
	    {
		if (parse->scanOnly && vstack->u.pattern)
		    FcPatternDestroy (vstack->u.pattern);
		vstack->tag = FcVStackNone;
	    }
	    break;
	default:
	    FcConfigMessage (parse, FcSevereWarning, "bad font selector");
	    break;
	}
	FcVStackPopAndDestroy (parse);
    }
}


static FcValue
FcPopValue (FcConfigParse *parse)
{
    FcVStack	*vstack = FcVStackPeek (parse);
    FcValue	value;

    value.type = FcTypeVoid;

    if (!vstack)
	return value;

    switch ((int) vstack->tag) {
    case FcVStackString:
	value.u.s = FcStrdup (vstack->u.string);
	if (value.u.s)
	    value.type = FcTypeString;
	break;
    case FcVStackConstant:
	if (FcNameConstant (vstack->u.string, &value.u.i))
	    value.type = FcTypeInteger;
	break;
    case FcVStackInteger:
	value.u.i = vstack->u.integer;
	value.type = FcTypeInteger;
	break;
    case FcVStackDouble:
	value.u.d = vstack->u._double;
	value.type = FcTypeDouble;
	break;
    case FcVStackBool:
	value.u.b = vstack->u.bool_;
	value.type = FcTypeBool;
	break;
    case FcVStackCharSet:
	value.u.c = FcCharSetCopy (vstack->u.charset);
	if (value.u.c)
	    value.type = FcTypeCharSet;
	break;
    case FcVStackLangSet:
	value.u.l = FcLangSetCopy (vstack->u.langset);
	if (value.u.l)
	    value.type = FcTypeLangSet;
	break;
    case FcVStackRange:
	value.u.r = FcRangeCopy (vstack->u.range);
	if (value.u.r)
	    value.type = FcTypeRange;
	break;
    default:
	FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
			 vstack->tag);
	break;
    }
    FcVStackPopAndDestroy (parse);

    return value;
}

static void
FcParsePatelt (FcConfigParse *parse)
{
    FcValue	value;
    FcPattern	*pattern = FcPatternCreate ();
    const char	*name;

    if (!pattern)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }

    name = (char *) FcConfigGetAttribute (parse, "name");
    if (!name)
    {
	FcConfigMessage (parse, FcSevereWarning, "missing pattern element name");
	FcPatternDestroy (pattern);
	return;
    }

    for (;;)
    {
	value = FcPopValue (parse);
	if (value.type == FcTypeVoid)
	    break;
	if (!FcPatternAdd (pattern, name, value, FcTrue))
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
            FcValueDestroy(value);
	    break;
	}
        FcValueDestroy(value);
    }

    FcVStackPushPattern (parse, pattern);
}

static void
FcParsePattern (FcConfigParse *parse)
{
    FcVStack	*vstack;
    FcPattern	*pattern = FcPatternCreate ();

    if (!pattern)
    {
	FcConfigMessage (parse, FcSevereError, "out of memory");
	return;
    }
	
    while ((vstack = FcVStackPeek (parse)))
    {
	switch ((int) vstack->tag) {
	case FcVStackPattern:
	    if (!FcPatternAppend (pattern, vstack->u.pattern))
	    {
		FcConfigMessage (parse, FcSevereError, "out of memory");
		FcPatternDestroy (pattern);
		return;
	    }
	    break;
	default:
	    FcConfigMessage (parse, FcSevereWarning, "unknown pattern element");
	    break;
	}
	FcVStackPopAndDestroy (parse);
    }

    FcVStackPushPattern (parse, pattern);
}

static void
FcEndElement(void *userData, const XML_Char *name FC_UNUSED)
{
    FcConfigParse   *parse = userData;
    FcChar8	    *data;

    if (!parse->pstack)
	return;
    switch (parse->pstack->element) {
    case FcElementNone:
	break;
    case FcElementFontconfig:
	break;
    case FcElementDir:
	FcParseDir (parse);
	break;
    case FcElementCacheDir:
	FcParseCacheDir (parse);
	break;
    case FcElementCache:
	data = FcStrBufDoneStatic (&parse->pstack->str);
	if (!data)
	{
	    FcConfigMessage (parse, FcSevereError, "out of memory");
	    break;
	}
	/* discard this data; no longer used */
	FcStrBufDestroy (&parse->pstack->str);
	break;
    case FcElementInclude:
	FcParseInclude (parse);
	break;
    case FcElementConfig:
	break;
    case FcElementMatch:
	FcParseMatch (parse);
	break;
    case FcElementAlias:
	FcParseAlias (parse);
	break;
    case FcElementDescription:
	FcParseDescription (parse);
	break;
    case FcElementRemapDir:
	FcParseRemapDir (parse);
	break;
    case FcElementResetDirs:
	FcParseResetDirs (parse);
	break;

    case FcElementRescan:
	FcParseRescan (parse);
	break;
	
    case FcElementPrefer:
	FcParseFamilies (parse, FcVStackPrefer);
	break;
    case FcElementAccept:
	FcParseFamilies (parse, FcVStackAccept);
	break;
    case FcElementDefault:
	FcParseFamilies (parse, FcVStackDefault);
	break;
    case FcElementFamily:
	FcParseFamily (parse);
	break;

    case FcElementTest:
	FcParseTest (parse);
	break;
    case FcElementEdit:
	FcParseEdit (parse);
	break;

    case FcElementInt:
	FcParseInt (parse);
	break;
    case FcElementDouble:
	FcParseDouble (parse);
	break;
    case FcElementString:
	FcParseString (parse, FcVStackString);
	break;
    case FcElementMatrix:
	FcParseMatrix (parse);
	break;
    case FcElementRange:
	FcParseRange (parse);
	break;
    case FcElementBool:
	FcParseBool (parse);
	break;
    case FcElementCharSet:
	FcParseCharSet (parse);
	break;
    case FcElementLangSet:
	FcParseLangSet (parse);
	break;
    case FcElementSelectfont:
	break;
    case FcElementAcceptfont:
    case FcElementRejectfont:
	FcParseAcceptRejectFont (parse, parse->pstack->element);
	break;
    case FcElementGlob:
	FcParseString (parse, FcVStackGlob);
	break;
    case FcElementPattern:
	FcParsePattern (parse);
	break;
    case FcElementPatelt:
	FcParsePatelt (parse);
	break;
    case FcElementName:
	FcParseName (parse);
	break;
    case FcElementConst:
	FcParseString (parse, FcVStackConstant);
	break;
    case FcElementOr:
	FcParseBinary (parse, FcOpOr);
	break;
    case FcElementAnd:
	FcParseBinary (parse, FcOpAnd);
	break;
    case FcElementEq:
	FcParseBinary (parse, FcOpEqual);
	break;
    case FcElementNotEq:
	FcParseBinary (parse, FcOpNotEqual);
	break;
    case FcElementLess:
	FcParseBinary (parse, FcOpLess);
	break;
    case FcElementLessEq:
	FcParseBinary (parse, FcOpLessEqual);
	break;
    case FcElementMore:
	FcParseBinary (parse, FcOpMore);
	break;
    case FcElementMoreEq:
	FcParseBinary (parse, FcOpMoreEqual);
	break;
    case FcElementContains:
	FcParseBinary (parse, FcOpContains);
	break;
    case FcElementNotContains:
	FcParseBinary (parse, FcOpNotContains);
	break;
    case FcElementPlus:
	FcParseBinary (parse, FcOpPlus);
	break;
    case FcElementMinus:
	FcParseBinary (parse, FcOpMinus);
	break;
    case FcElementTimes:
	FcParseBinary (parse, FcOpTimes);
	break;
    case FcElementDivide:
	FcParseBinary (parse, FcOpDivide);
	break;
    case FcElementNot:
	FcParseUnary (parse, FcOpNot);
	break;
    case FcElementIf:
	FcParseBinary (parse, FcOpQuest);
	break;
    case FcElementFloor:
	FcParseUnary (parse, FcOpFloor);
	break;
    case FcElementCeil:
	FcParseUnary (parse, FcOpCeil);
	break;
    case FcElementRound:
	FcParseUnary (parse, FcOpRound);
	break;
    case FcElementTrunc:
	FcParseUnary (parse, FcOpTrunc);
	break;
    case FcElementUnknown:
	break;
    }
    (void) FcPStackPop (parse);
}

static void
FcCharacterData (void *userData, const XML_Char *s, int len)
{
    FcConfigParse   *parse = userData;

    if (!parse->pstack)
	return;
    if (!FcStrBufData (&parse->pstack->str, (FcChar8 *) s, len))
	FcConfigMessage (parse, FcSevereError, "out of memory");
}

static void
FcStartDoctypeDecl (void	    *userData,
		    const XML_Char  *doctypeName,
		    const XML_Char  *sysid FC_UNUSED,
		    const XML_Char  *pubid FC_UNUSED,
		    int		    has_internal_subset FC_UNUSED)
{
    FcConfigParse   *parse = userData;

    if (strcmp ((char *) doctypeName, "fontconfig") != 0)
	FcConfigMessage (parse, FcSevereError, "invalid doctype \"%s\"", doctypeName);
}

#ifdef ENABLE_LIBXML2

static void
FcInternalSubsetDecl (void            *userData,
		      const XML_Char  *doctypeName,
		      const XML_Char  *sysid,
		      const XML_Char  *pubid)
{
    FcStartDoctypeDecl (userData, doctypeName, sysid, pubid, 1);
}

static void
FcExternalSubsetDecl (void            *userData,
		      const XML_Char  *doctypeName,
		      const XML_Char  *sysid,
		      const XML_Char  *pubid)
{
    FcStartDoctypeDecl (userData, doctypeName, sysid, pubid, 0);
}

#else /* ENABLE_LIBXML2 */

static void
FcEndDoctypeDecl (void *userData FC_UNUSED)
{
}

#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,
			 const FcChar8	*dir,
			 FcBool		complain,
			 FcBool		load)
{
    DIR		    *d;
    struct dirent   *e;
    FcBool	    ret = FcTrue;
    FcChar8	    *file;
    FcChar8	    *base;
    FcStrSet	    *files;

    d = opendir ((char *) dir);
    if (!d)
    {
	if (complain)
	    FcConfigMessage (0, FcSevereError, "Cannot open config dir \"%s\"",
			     name);
	ret = FcFalse;
	goto bail0;
    }
    /* freed below */
    file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
    if (!file)
    {
	ret = FcFalse;
	goto bail1;
    }

    strcpy ((char *) file, (char *) dir);
    strcat ((char *) file, "/");
    base = file + strlen ((char *) file);

    files = FcStrSetCreateEx (FCSS_GROW_BY_64);
    if (!files)
    {
	ret = FcFalse;
	goto bail2;
    }

    if (FcDebug () & FC_DBG_CONFIG)
	printf ("\tScanning config dir %s\n", dir);

    if (load)
	FcConfigAddConfigDir (config, dir);

    while (ret && (e = readdir (d)))
    {
	int d_len;
#define TAIL	    ".conf"
#define TAIL_LEN    5
	/*
	 * Add all files of the form [0-9]*.conf
	 */
	d_len = strlen (e->d_name);
	if ('0' <= e->d_name[0] && e->d_name[0] <= '9' &&
	    d_len > TAIL_LEN &&
	    strcmp (e->d_name + d_len - TAIL_LEN, TAIL) == 0)
	{
	    strcpy ((char *) base, (char *) e->d_name);
	    if (!FcStrSetAdd (files, file))
	    {
		ret = FcFalse;
		goto bail3;
	    }
	}
    }
    if (ret)
    {
	int i;
	qsort (files->strs, files->num, sizeof (FcChar8 *),
	       (int (*)(const void *, const void *)) FcSortCmpStr);
	for (i = 0; ret && i < files->num; i++)
	    ret = _FcConfigParse (config, files->strs[i], complain, load);
    }
bail3:
    FcStrSetDestroy (files);
bail2:
    free (file);
bail1:
    closedir (d);
bail0:
    return ret || !complain;
}

#ifdef _WIN32
pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory = NULL;
pfnSHGetFolderPathA pSHGetFolderPathA = NULL;
#endif

static FcBool
FcConfigParseAndLoadFromMemoryInternal (FcConfig       *config,
					const FcChar8  *filename,
					const FcChar8  *buffer,
					FcBool         complain,
					FcBool         load)
{

    XML_Parser	    p;
    size_t	    len;
    FcConfigParse   parse;
    FcBool	    error = FcTrue;
    FcMatchKind	    k;
    FcPtrListIter   liter;

#ifdef ENABLE_LIBXML2
    xmlSAXHandler   sax;
#else
    void            *buf;
    const FcChar8   *s;
    size_t	    buflen;
#endif

    if (!buffer)
	return FcFalse;
    len = strlen ((const char *) buffer);
    if (FcDebug () & FC_DBG_CONFIG)
	printf ("\t%s config file from %s\n", load ? "Loading" : "Scanning", filename);

#ifdef ENABLE_LIBXML2
    memset(&sax, 0, sizeof(sax));

    sax.internalSubset = FcInternalSubsetDecl;
    sax.externalSubset = FcExternalSubsetDecl;
    sax.startElement = FcStartElement;
    sax.endElement = FcEndElement;
    sax.characters = FcCharacterData;

    p = xmlCreatePushParserCtxt (&sax, &parse, NULL, 0, (const char *) filename);
#else
    p = XML_ParserCreate ("UTF-8");
#endif

    if (!p)
	goto bail1;

    if (!FcConfigParseInit (&parse, filename, config, p, load))
	goto bail2;

#ifndef ENABLE_LIBXML2

    XML_SetUserData (p, &parse);

    XML_SetDoctypeDeclHandler (p, FcStartDoctypeDecl, FcEndDoctypeDecl);
    XML_SetElementHandler (p, FcStartElement, FcEndElement);
    XML_SetCharacterDataHandler (p, FcCharacterData);
	
#endif /* ENABLE_LIBXML2 */

#ifndef ENABLE_LIBXML2
    s = buffer;
    do {
	buf = XML_GetBuffer (p, BUFSIZ);
	if (!buf)
	{
	    FcConfigMessage (&parse, FcSevereError, "cannot get parse buffer");
	    goto bail3;
	}
	if (len > BUFSIZ)
	{
	    buflen = BUFSIZ;
	    len -= BUFSIZ;
	}
	else
	{
	    buflen = len;
	    len = 0;
	}
	memcpy (buf, s, buflen);
	s = s + buflen;
#endif

#ifdef ENABLE_LIBXML2
	if (xmlParseChunk (p, (const char *)buffer, len, len == 0))
#else
	if (!XML_ParseBuffer (p, buflen, buflen == 0))
#endif
	{
	    FcConfigMessage (&parse, FcSevereError, "%s",
			   XML_ErrorString (XML_GetErrorCode (p)));
	    goto bail3;
	}
#ifndef ENABLE_LIBXML2
    } while (buflen != 0);
#endif
    error = parse.error;
    if (load)
    {
	for (k = FcMatchKindBegin; k < FcMatchKindEnd; k++)
	{
	    FcPtrListIter iter;

	    FcPtrListIterInit (parse.ruleset->subst[k], &iter);
	    if (FcPtrListIterIsValid (parse.ruleset->subst[k], &iter))
	    {
		FcPtrListIterInitAtLast (parse.config->subst[k], &iter);
		FcRuleSetReference (parse.ruleset);
		FcPtrListIterAdd (parse.config->subst[k], &iter, parse.ruleset);
	    }
	}
    }
    FcPtrListIterInitAtLast (parse.config->rulesetList, &liter);
    FcRuleSetReference (parse.ruleset);
    FcPtrListIterAdd (parse.config->rulesetList, &liter, parse.ruleset);
bail3:
    FcConfigCleanup (&parse);
bail2:
    XML_ParserFree (p);
bail1:
    if (error && complain)
    {
	FcConfigMessage (0, FcSevereError, "Cannot %s config file from %s", load ? "load" : "scan", filename);
	return FcFalse;
    }
    if (FcDebug () & FC_DBG_CONFIG)
	printf ("\t%s config file from %s done\n", load ? "Loading" : "Scanning", filename);
    return FcTrue;
}

static FcBool
_FcConfigParse (FcConfig	*config,
		const FcChar8	*name,
		FcBool		complain,
		FcBool		load)
{
    FcChar8	    *filename = NULL, *realfilename = NULL;
    int		    fd;
    int		    len;
    FcStrBuf	    sbuf;
    char            buf[BUFSIZ];
    FcBool	    ret = FcFalse;

#ifdef _WIN32
    if (!pGetSystemWindowsDirectory)
    {
        HMODULE hk32 = GetModuleHandleA("kernel32.dll");
        if (!(pGetSystemWindowsDirectory = (pfnGetSystemWindowsDirectory) GetProcAddress(hk32, "GetSystemWindowsDirectoryA")))
            pGetSystemWindowsDirectory = (pfnGetSystemWindowsDirectory) GetWindowsDirectory;
    }
    if (!pSHGetFolderPathA)
    {
        HMODULE hSh = LoadLibraryA("shfolder.dll");
        /* the check is done later, because there is no provided fallback */
        if (hSh)
            pSHGetFolderPathA = (pfnSHGetFolderPathA) GetProcAddress(hSh, "SHGetFolderPathA");
    }
#endif

    filename = FcConfigFilename (name);
    if (!filename)
	goto bail0;
    realfilename = FcConfigRealFilename (config, name);
    if (!realfilename)
	goto bail0;
    if (FcStrSetMember (config->availConfigFiles, realfilename))
    {
        FcStrFree (filename);
	FcStrFree (realfilename);
        return FcTrue;
    }

    if (load)
    {
	if (!FcStrSetAdd (config->configFiles, filename))
	    goto bail0;
    }
    if (!FcStrSetAdd (config->availConfigFiles, realfilename))
	goto bail0;

    if (FcFileIsDir (realfilename))
    {
	ret = FcConfigParseAndLoadDir (config, name, realfilename, complain, load);
	FcStrFree (filename);
	FcStrFree (realfilename);
	return ret;
    }

    FcStrBufInit (&sbuf, NULL, 0);

    fd = FcOpen ((char *) realfilename, O_RDONLY);
    if (fd == -1)
	goto bail1;

    do {
	len = read (fd, buf, BUFSIZ);
	if (len < 0)
	{
	    int errno_ = errno;
	    char ebuf[BUFSIZ+1];

#if HAVE_STRERROR_R
	    strerror_r (errno_, ebuf, BUFSIZ);
#elif HAVE_STRERROR
	    char *tmp = strerror (errno_);
	    size_t len = strlen (tmp);
	    strncpy (ebuf, tmp, FC_MIN (BUFSIZ, len));
	    ebuf[FC_MIN (BUFSIZ, len)] = 0;
#else
	    ebuf[0] = 0;
#endif
	    FcConfigMessage (0, FcSevereError, "failed reading config file: %s: %s (errno %d)", realfilename, ebuf, errno_);
	    close (fd);
	    goto bail1;
	}
	FcStrBufData (&sbuf, (const FcChar8 *)buf, len);
    } while (len != 0);
    close (fd);

    ret = FcConfigParseAndLoadFromMemoryInternal (config, filename, FcStrBufDoneStatic (&sbuf), complain, load);
    complain = FcFalse; /* no need to reclaim here */
bail1:
    FcStrBufDestroy (&sbuf);
bail0:
    if (filename)
	FcStrFree (filename);
    if (realfilename)
	FcStrFree (realfilename);
    if (!ret && complain)
    {
	if (name)
	    FcConfigMessage (0, FcSevereError, "Cannot %s config file \"%s\"", load ? "load" : "scan", name);
	else
	    FcConfigMessage (0, FcSevereError, "Cannot %s default config file", load ? "load" : "scan");
	return FcFalse;
    }
    return FcTrue;
}

FcBool
FcConfigParseOnly (FcConfig		*config,
		   const FcChar8	*name,
		   FcBool		complain)
{
    return _FcConfigParse (config, name, complain, FcFalse);
}

FcBool
FcConfigParseAndLoad (FcConfig	    *config,
		      const FcChar8 *name,
		      FcBool	    complain)
{
    return _FcConfigParse (config, name, complain, FcTrue);
}

FcBool
FcConfigParseAndLoadFromMemory (FcConfig       *config,
				const FcChar8  *buffer,
				FcBool         complain)
{
    return FcConfigParseAndLoadFromMemoryInternal (config, (const FcChar8 *)"memory", buffer, complain, FcTrue);
}

#define __fcxml__
#include "fcaliastail.h"
#undef __fcxml__
